invalid byte sequence for encoding UTF8: 0x00

Postgres text can't hold the NUL character (0x00) or bytes that aren't valid UTF-8. Where the error comes from in imports and API inserts, and how to clean the data.

What you see

When importing a CSV, restoring a dump, or inserting from your app:

ERROR:  invalid byte sequence for encoding "UTF8": 0x00
CONTEXT:  COPY messages, line 1842

Sending JSON with a NUL character into a jsonb or text column through the Data API gives a close relative:

ERROR:  unsupported Unicode escape sequence
DETAIL:  \u0000 cannot be converted to text.

Both have SQLSTATE 22021 or 22P05. A different byte in the message, such as 0xe9 0x20, means the file isn't UTF-8 at all (often Latin-1 or Windows-1252).

Why it happens

Project databases use the UTF-8 encoding (check with show server_encoding;), and Postgres text, varchar and jsonb values can't contain the NUL character. Other databases and languages allow it, so it sneaks in from:

  • data scraped from PDFs or binary files,
  • exports from SQLite or MySQL,
  • strings from C libraries or badly decoded uploads,
  • JSON payloads where a client wrote "\u0000".

The value is rejected while Postgres converts the input, before any trigger runs. A trigger can't clean it up for you; the fix has to happen before the data reaches the database.

How to fix it

Strip NUL characters in your app before writing:

const clean = (s: string) => s.replaceAll('\u0000', '')

await supabase.from('messages').insert({
  channel_id: channelId,
  body: clean(rawBody),
})

For nested objects, run the same function over every string value before sending.

Clean a CSV or SQL file before importing:

# remove NUL bytes
tr -d '\000' < messages.csv > messages-clean.csv

# convert a Latin-1 file to UTF-8
iconv -f LATIN1 -t UTF-8 export.csv > export-utf8.csv

Then import the cleaned file. In psql, \copy messages from 'messages-clean.csv' with (format csv, header true).

If the data really is binary, store it in a bytea column, or better, as a file in Storage with only its path in the table.

On SupaHost

  • For large imports, see Importing data. On Business you can run \copy through the SSH tunnel; on other plans use Studio's CSV import or insert in batches through the Data API.

Updated 11 November 2026 · View as Markdown · Something wrong or missing? Tell us