Skip to content

22P03 — invalid_binary_representation

Source-backed reference for PostgreSQL SQLSTATE 22P03.

22P03

At a glance

22P03 is PostgreSQL’s invalid-binary-representation boundary. In the fixed source it covers binary COPY fields, extended-protocol Bind parameters, fast-path function arguments, logical-replication columns, and guards inside representative type receive functions.

Field Value
SQLSTATE 22P03
Condition invalid_binary_representation
Status active
Known present by 7.4
Locked snapshots 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3
Macros ERRCODE_INVALID_BINARY_REPRESENTATION
Aliases

Meaning

The receiver has been told to decode binary bytes, but the bytes do not satisfy the receiver’s format or do not get consumed completely. Binary COPY calls a type receive function and reports incorrect binary data format when bytes remain. Bind reports incorrect binary data format in bind parameter %d; fast-path calls report incorrect binary data format in function argument %d; logical replication reports incorrect binary data format in logical replication column %d. Representative array and numeric receivers use the same SQLSTATE for invalid dimensions/flags, array element framing, or numeric sign/scale/digit fields.

This is different from text input that fails a type input routine, and from COPY header or row framing errors that use 22P04. The exact receiving boundary and type OID matter.

Messages

The fixed representative primaries are incorrect binary data format (binary COPY), incorrect binary data format in bind parameter %d (Bind), incorrect binary data format in function argument %d (fast-path), and incorrect binary data format in logical replication column %d (logical replication). Type receivers also use invalid number of dimensions: %d, invalid array flags, insufficient data left in message, improper binary format in array element %d, invalid sign in external "numeric" value, invalid scale in external "numeric" value, and invalid digit in external "numeric" value; all cited variants are ERROR and have no DETAIL or HINT in the fixed calls.

Diagnosis

First identify the transport: extended-protocol Bind, binary COPY, fast-path function call, logical replication, or a type’s binary receive function. Preserve the parameter, argument, or remote-column number and the complete message. Compare the producer’s format code and type OID with the receiver’s expected type. For receiver guards, check whether the type consumed the complete length-delimited buffer; a leftover cursor is evidence of a format mismatch, not merely a bad textual value.

Response

Correct the producer or type contract, then retry at the protocol boundary that failed. Every client-visible ERROR inside an explicit transaction leaves that transaction aborted, including a Bind error: issue ROLLBACK or an already-established ROLLBACK TO SAVEPOINT before retrying. Sync and ReadyForQuery restore protocol synchronization and report status; they do not clear INERROR. For an extended-protocol Bind error, the backend skips frontend messages until the next Sync; send Sync and consume ReadyForQuery before issuing another extended-protocol operation. In autocommit, wait for that boundary before resubmitting the corrected operation. A fast-path FunctionCall is handled outside the extended-query skip flag and the normal loop can return ReadyForQuery, but the same explicit-transaction recovery rule applies. For COPY FROM STDIN, terminate a malformed stream according to the COPY protocol, using CopyFail when appropriate while still in COPY-in. If the COPY was issued through the extended protocol, after ErrorResponse send Sync and wait for ReadyForQuery; if it was issued in a simple Query, the remaining query message is discarded and ReadyForQuery follows; no client Sync is required, so consume that ReadyForQuery before sending the next query. Do not issue ordinary SQL during COPY-in. If message framing itself was lost while reading from the client, PostgreSQL has a separate protocol-synchronization FATAL path; do not infer that connection loss from the binary-format ERROR alone. For logical replication, repair the publisher/receiver binary encoder or type definition and let the replication worker’s own retry policy apply; this page does not justify killing or resetting every connection.

Versions

The locked catalogue records this condition from PostgreSQL 7.4. The binary transport, replication, array, and numeric paths cited here are from PostgreSQL 18.6 REL_18_6; no binary-protocol runtime was executed.

22P02, 22P04, 08P01

Sources

src/backend/commands/copyfromparse.c#L2047-L2055

src/backend/tcop/postgres.c#L1922-L1945

src/backend/tcop/fastpath.c#L426-L448

src/backend/replication/logical/worker.c#L832-L853

src/backend/utils/adt/arrayfuncs.c#L1476-L1510

src/backend/utils/adt/numeric.c#L1093-L1123

src/backend/tcop/postgres.c#L416-L445

src/backend/tcop/postgres.c#L4483-L4504

src/backend/tcop/postgres.c#L4843-L4875

doc/src/sgml/protocol.sgml#L1287-L1318

doc/src/sgml/protocol.sgml#L7821-L7823

The structured evidence record records exact primary templates and the source/runtime boundary.