PostgreSQL error 22P03 occurs when binary data format is invalid or mismatched with the column type. This happens with bytea columns, COPY BINARY operations, or client driver encoding issues.
PostgreSQL error code 22P03 indicates that the database received binary data in a format it cannot interpret. This typically occurs when inserting or updating bytea (binary) data with incorrect formatting, using binary COPY operations with misaligned data structures, or when client applications fail to properly encode binary values. The error signals a mismatch between what PostgreSQL expects and what it received.
When inserting binary data directly in SQL, use the correct format:
-- Correct: hex format with \x prefix (preferred)
INSERT INTO table_name (binary_column) VALUES (E'\xdeadbeef');
-- Correct: escape format with E prefix and double backslashes
INSERT INTO table_name (binary_column) VALUES (E'\\x41\\x42');
-- Incorrect: missing \x prefix or improper escaping
INSERT INTO table_name (binary_column) VALUES ('deadbeef');The hex format (\xHEXVALUES) is preferred because it's faster and compatible with more external tools.
Ensure your PostgreSQL connection encoding matches your application encoding:
-- Check server encoding
SHOW server_encoding;
-- Check client encoding
SHOW client_encoding;
-- Set client encoding if needed (must be done before operations)
SET client_encoding = 'UTF8';If your application uses a different encoding, either change the application encoding or explicitly convert the binary data before insertion.
When using COPY ... FROM BINARY, ensure data structure alignment:
-- Verify your binary file matches the column layout
COPY table_name (col1, col2) FROM STDIN WITH (FORMAT binary);
-- If importing fails, validate with text format first
COPY table_name (col1, col2) FROM STDIN WITH (FORMAT text);Binary COPY expects strict byte-for-byte alignment with column types (int2 = 2 bytes, int4 = 4 bytes, bytea includes length prefix). If importing from another tool, verify the binary structure matches PostgreSQL's internal format.
If using an ORM (Prisma, Sequelize, SQLAlchemy) or database driver (libpq, Npgsql, psycopg), verify it's properly encoding binary data:
// Prisma example: ensure proper Buffer handling
const data = Buffer.from('deadbeef', 'hex');
await prisma.table.create({ data: { binaryColumn: data } });
// Node.js with pg driver
const client = new Client();
await client.query(
'INSERT INTO table_name (binary_col) VALUES ($1)',
[Buffer.from('deadbeef', 'hex')]
);If the error persists, check driver documentation for binary protocol mode settings or consider using text format as a temporary workaround.
Test your binary data with a simple query before bulk import:
-- Create a test bytea column with sample data
CREATE TABLE test_binary (id SERIAL, data bytea);
-- Try inserting a small sample
INSERT INTO test_binary (data) VALUES (E'\xdeadbeef');
SELECT * FROM test_binary;
-- If successful, try importing larger dataset in smaller chunks
COPY test_binary (data) FROM STDIN WITH (FORMAT binary);If the sample succeeds but bulk import fails, the issue is likely data corruption or format mismatch in the larger dataset.
PostgreSQL bytea supports two legacy input formats: hex (preferred, faster, more compatible) and escape (traditional). The escape format requires the E prefix and double backslashes, making it error-prone. When migrating from MySQL BLOB or other databases, verify the binary representation matches PostgreSQL's expectations.
For binary COPY operations, PostgreSQL uses a strict binary protocol that includes type OIDs (Object IDs) and length prefixes. Misaligned structure (e.g., sending 2 bytes for an int4 field) will cause this error even if the values are semantically correct. If debugging binary COPY failures, enable verbose logging with "SET log_statement = 'all';" and check the PostgreSQL logs for additional context.
Some ORMs switched from text to binary protocol for performance (Npgsql moved to binary by default), which can trigger this error if the driver doesn't properly serialize types. Check the driver version and consider reverting to text mode temporarily while investigating.
ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL