# 22P03 — invalid_binary_representation

> Source-backed reference for PostgreSQL SQLSTATE 22P03.
---

# 22P03

## At a glance {#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.

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| 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 | `—` |

<!-- source facts: data/errcodes/22P03.json -->
<!-- END SQLSTATE FACTS -->

## Meaning {#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 {#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 {#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 {#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 {#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.

## Related {#related}
[`22P02`](../22p02/), [`22P04`](../22p04/), [`08P01`](../08p01/)

## Sources {#sources}
[`src/backend/commands/copyfromparse.c#L2047-L2055`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/copyfromparse.c#L2047)

[`src/backend/tcop/postgres.c#L1922-L1945`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/postgres.c#L1922)

[`src/backend/tcop/fastpath.c#L426-L448`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/fastpath.c#L426)

[`src/backend/replication/logical/worker.c#L832-L853`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/replication/logical/worker.c#L832)

[`src/backend/utils/adt/arrayfuncs.c#L1476-L1510`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/arrayfuncs.c#L1476)

[`src/backend/utils/adt/numeric.c#L1093-L1123`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/numeric.c#L1093)

[`src/backend/tcop/postgres.c#L416-L445`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/postgres.c#L416)

[`src/backend/tcop/postgres.c#L4483-L4504`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/postgres.c#L4483)

[`src/backend/tcop/postgres.c#L4843-L4875`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/postgres.c#L4843)

[`doc/src/sgml/protocol.sgml#L1287-L1318`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/doc/src/sgml/protocol.sgml#L1287-L1318)

[`doc/src/sgml/protocol.sgml#L7821-L7823`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/doc/src/sgml/protocol.sgml#L7821-L7823)

The structured [evidence record](../data/evidence/22p03.json) records exact primary templates and the source/runtime boundary.
