term_to_binary/1,2 produces a binary in the external term format, not a UTF-8-encoded binary, so this seems like a problem with the schema (by the looks of it on the database server side). Try looking into why field :state, :binary implies UTF-8 encoding.
My guess is that its resulting from an encoding error in either the owner or version fields since the Postgres text type maps to Elixir String.t type - which is UTF-8. Therefore one possible cause is that that either the Postgres database or the database connection string are set to LATIN-9 or some other non-UTF-8 encoding.
The bytea type maps to Elixir/erlang binary as you have configured.
While I was trying to narrow down the problem I got a different error message:
09:44:01.258 [error] GenServer #PID<0.7186.0> terminating
** (Postgrex.Error) ERROR 22023 (invalid_parameter_value) payload string too long
(ecto_sql 3.11.0) lib/ecto/adapters/sql.ex:1054: Ecto.Adapters.SQL.raise_sql_call_error/1
Which leads to the real problem
The table has a trigger attached - and that trigger is converting the updated/inserted table row to JSON to send a message using pg_notify => trying to convert the binary data…
And I was able to verify it as soon as I had a look at the postgresql log files