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
\copythrough the SSH tunnel; on other plans use Studio's CSV import or insert in batches through the Data API.