# 22P04 — bad_copy_file_format

> PostgreSQL SQLSTATE 22P04 的来源与诊断参考。
---

# 22P04

## 速览 {#at-a-glance}
`22P04` 是 COPY 文件格式边界。固定解析器在二进制签名和头部、文本或 CSV 帧、头部/行字段数以及二进制字段长度错误时使用它。它表示 COPY 结构错误，不是所有值转换失败的统称。

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

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `22P04` |
| 条件名 | `bad_copy_file_format` |
| 状态 | `有效` |
| 已知存在于 | `7.4` |
| 锁定快照 | `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` |
| 宏 | `ERRCODE_BAD_COPY_FILE_FORMAT` |
| 别名 | `—` |

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

## 含义 {#meaning}
二进制输入会校验 `PGCOPY` 签名、flags、扩展长度、行字段数、字段长度和结束标记。代表性主消息包括 `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` 和 `unexpected EOF in COPY data`。

文本和 CSV 有独立的帧检查。头部匹配可能报告 `wrong number of fields in header line: got %d, expected %d` 或列名不匹配；普通行可能报告 `extra data after last expected column` 或 `missing data for column "%s"`。CSV 引号和换行可能报告 `unterminated CSV quoted field`、`unquoted carriage return found in data` 或 `unquoted newline found in data`；文本模式使用对应的 `literal ... found in data` 消息和提示。帧已正确解析但值无法转换时通常属于 `22P02`；二进制类型接收函数留下未消费字节时可能是 `22P03`。

## 报文 {#messages}
固定源码中的代表性主消息均为 `ERROR`：

- 二进制头部/字段：`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`。
- 头部和行：`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 和行帧：`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`。回车/换行变体还会携带使用 `\r`、`\n` 或带引号 CSV 字段的源码提示。

## 诊断 {#diagnosis}
先确定来源是文本、CSV、二进制 COPY 还是前端 COPY-in。保留完整主消息，因为它能定位解析阶段。依次检查二进制签名/标志位/长度、头部和目标列顺序、行字段数、CSV 引号/转义与换行规则，以及文本 COPY 的数据结束标记是否单独占行，之后再检查目标类型的输入转换。

`ON_ERROR IGNORE` 不是通用的坏行跳过开关。固定文本/CSV 路径会围绕安全的类型输入转换处理软错误，并可发出通知后跳过数据类型不兼容的行；头部、字段数、行帧、CSV 引号和二进制结构错误仍以 `ERROR` 抛出，不能都靠这个选项跳过。

## 处理 {#response}
按声明的文本/CSV/二进制格式、目标列顺序，重新生成带正确头部、长度、引号和行格式的流。前端 COPY-in 出错时，按当前 COPY 子协议状态结束输入，适当时使用 `CopyFail`。如果 COPY 由扩展协议发起且后端发送 `ErrorResponse`，客户端应发送 `Sync` 并等待 `ReadyForQuery`；如果由 simple `Query` 发起，剩余查询消息会被丢弃，随后直接发送 `ReadyForQuery`；客户端不需要发送 `Sync`，消费该 `ReadyForQuery` 后再发送下一条查询。不要在 COPY-in 期间发送普通 SQL。显式事务中的 `ERROR` 要在协议边界恢复后执行 `ROLLBACK` 或 `ROLLBACK TO SAVEPOINT`；`ReadyForQuery` 只报告状态，不能替代事务恢复。`ON_ERROR IGNORE` 只可能适用于文档所说的安全类型输入失败，不能修复坏头或损坏的 CSV/二进制帧。普通 COPY ERROR 本身不要求重置连接。

## 版本 {#versions}
锁定目录从 PostgreSQL `7.4` 记录此条件。引用的解析器及 `ON_ERROR` 边界来自 PostgreSQL 18.6 `REL_18_6`；本次没有运行自然 COPY 文件案例。

## 相关 {#related}
[`22P02`](../22p02/)、[`22P03`](../22p03/)、[`2200B`](../2200b/)

## 来源 {#sources}
[`src/backend/commands/copyfromparse.c#L190-L228`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/copyfromparse.c#L190)

[`src/backend/commands/copyfromparse.c#L779-L827`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/copyfromparse.c#L779)

[`src/backend/commands/copyfromparse.c#L937-L977`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/copyfromparse.c#L937)

[`src/backend/commands/copyfromparse.c#L1026-L1073`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/copyfromparse.c#L1026)

[`src/backend/commands/copyfromparse.c#L1084-L1130`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/copyfromparse.c#L1084)

[`src/backend/commands/copyfromparse.c#L1388-L1432`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/copyfromparse.c#L1388)

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

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

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

结构化[证据记录](../../data/evidence/22p04.json)保存代表性精确主消息/提示以及 `ON_ERROR` 的结构边界。
