Skip to content

22P04 — bad_copy_file_format

Source-backed reference for PostgreSQL SQLSTATE 22P04.

22P04

At a glance

22P04 is the COPY file-format boundary. The fixed parser uses it for binary signatures and headers, text or CSV framing, header/row field counts, and malformed binary field lengths. It is a structural COPY error, not a generic synonym for a value that failed type conversion.

Field Value
SQLSTATE 22P04
Condition bad_copy_file_format
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_BAD_COPY_FILE_FORMAT
Aliases

Meaning

Binary input validates the PGCOPY signature, flags, extension length, row field count, field length, and end marker. Representative primaries include COPY file signature not recognized, invalid COPY file header (missing flags), invalid COPY file header (wrong length), row field count is %d, expected %d, invalid field size, and unexpected EOF in COPY data.

Text and CSV input has separate framing guards. Header matching can report wrong number of fields in header line: got %d, expected %d or a column-name mismatch; ordinary rows can report extra data after last expected column or missing data for column "%s". CSV quoting and line endings can report unterminated CSV quoted field, unquoted carriage return found in data, or unquoted newline found in data, while text mode uses the corresponding literal ... found in data messages and hints. A valid frame whose value cannot be converted belongs to the type-input boundary, commonly 22P02; a binary type receiver that leaves bytes unconsumed can be 22P03.

Messages

Representative fixed ERROR primaries include:

  • Binary headers/fields: COPY file signature not recognized; invalid COPY file header (missing flags); unrecognized critical flags in COPY file header; invalid COPY file header (missing length); invalid COPY file header (wrong length); invalid field size; unexpected EOF in COPY data.
  • Header and rows: wrong number of fields in header line: got %d, expected %d; column name mismatch in header line field %d: got "%s", expected "%s"; extra data after last expected column; missing data for column "%s"; row field count is %d, expected %d.
  • CSV and line framing: unterminated CSV quoted field; literal carriage return found in data; unquoted carriage return found in data; literal newline found in data; unquoted newline found in data; end-of-copy marker is not alone on its line. The carriage-return/newline variants carry the source hints to use \r, \n, or a quoted CSV field.

Diagnosis

Determine whether the source is text, CSV, binary COPY, or frontend COPY-in. Preserve the exact primary because it identifies the parser stage. Check binary signature/flags/length, header and target-column order, row field count, CSV quote/escape and newline rules, and whether the text COPY end-of-data marker is alone on its line. Only after framing is valid should you investigate the target type’s input conversion.

ON_ERROR IGNORE is narrower than a general malformed-row switch. The fixed text/CSV path wraps safe type-input conversion and can emit a notice while skipping a data-type-incompatible row; header, field-count, line-framing, CSV-quote, and binary-structure errors are raised as ERROR and are not all skippable through that option.

Response

Regenerate the stream in the declared text/CSV/binary format with the exact target column order and correct headers, lengths, quoting, and row framing. In frontend COPY-in, finish the COPY sub-protocol at its current boundary, using CopyFail when appropriate. If the COPY was issued through the extended protocol and the backend sends 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 send ordinary SQL in the middle of COPY-in. An ERROR inside an explicit transaction requires ROLLBACK or ROLLBACK TO SAVEPOINT after the protocol boundary; ReadyForQuery reports status but does not replace that transaction recovery. ON_ERROR IGNORE may be suitable for the documented safe type-input failures, but it does not repair a bad header or malformed CSV/binary framing. A normal COPY ERROR does not by itself require resetting the connection.

Versions

The locked catalogue records this condition from PostgreSQL 7.4. The cited parser and its ON_ERROR boundary are from PostgreSQL 18.6 REL_18_6; no natural COPY-file runtime was executed.

22P02, 22P03, 2200B

Sources

src/backend/commands/copyfromparse.c#L190-L228

src/backend/commands/copyfromparse.c#L779-L827

src/backend/commands/copyfromparse.c#L937-L977

src/backend/commands/copyfromparse.c#L1026-L1073

src/backend/commands/copyfromparse.c#L1084-L1130

src/backend/commands/copyfromparse.c#L1388-L1432

src/backend/commands/copyfromparse.c#L1818-L1922

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

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

The structured evidence record records representative exact primaries/hints and the structural ON_ERROR limit.