jackc/pgx · error
too many column format codes
Error message
too many column format codes
What it means
Returned by CopyOutResponse.Encode when ColumnFormatCodes has more than 65535 entries. The column count is a uint16 on the wire, so the library rejects oversized slices rather than truncating. CopyOutResponse is the 'H' message the server sends to begin a COPY TO STDOUT (server→client export) operation.
Source
Thrown at pgproto3/copy_out_response.go:53
columnFormatCodes := make([]uint16, columnCount)
for i := range columnCount {
columnFormatCodes[i] = binary.BigEndian.Uint16(buf.Next(2))
}
*dst = CopyOutResponse{OverallFormat: overallFormat, ColumnFormatCodes: columnFormatCodes}
return nil
}
// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
func (src *CopyOutResponse) Encode(dst []byte) ([]byte, error) {
dst, sp := beginMessage(dst, 'H')
dst = append(dst, src.OverallFormat)
if len(src.ColumnFormatCodes) > math.MaxUint16 {
return nil, errors.New("too many column format codes")
}
dst = pgio.AppendUint16(dst, uint16(len(src.ColumnFormatCodes)))
for _, fc := range src.ColumnFormatCodes {
dst = pgio.AppendUint16(dst, fc)
}
return finishMessage(dst, sp)
}
// MarshalJSON implements encoding/json.Marshaler.
func (src CopyOutResponse) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type string
ColumnFormatCodes []uint16
}{
Type: "CopyOutResponse",
ColumnFormatCodes: src.ColumnFormatCodes,
})View on GitHub (pinned to ec1a0befd2)
Solutions
- Cap ColumnFormatCodes at 65535; a one-element slice applies the format to all columns.
- Inspect the construction code for an unbounded or per-row append loop.
- When proxying, pass through the server's raw encoded bytes instead of re-encoding.
- Confirm the column count value is not a corrupted upstream read.
Example fix
// before
resp := &pgproto3.CopyOutResponse{
OverallFormat: 0,
ColumnFormatCodes: hugeCodes, // > 65535
}
_, err := resp.Encode(nil)
// after
resp := &pgproto3.CopyOutResponse{
OverallFormat: 0,
ColumnFormatCodes: []uint16{0},
}
_, err := resp.Encode(nil) Defensive patterns
Strategy: validation
Validate before calling
func validateCopyOutResponseEncode(r *pgproto3.CopyOutResponse) error {
if len(r.ColumnFormatCodes) > math.MaxUint16 {
return fmt.Errorf("too many column format codes: %d (max %d)", len(r.ColumnFormatCodes), math.MaxUint16)
}
return nil
} Type guard
null
Try / catch
null
Prevention
- Use a one-element ColumnFormatCodes slice for uniform formats.
- Cap column counts at 65535.
- Forward server bytes verbatim in proxies.
When it happens
Trigger: Calling `(*CopyOutResponse).Encode(dst)` with `len(ColumnFormatCodes) > 65535`. Like the other Copy responses, this is server-originated; the error only fires in a proxy/server/test harness, not in a standard pgx client.
Common situations: A proxy or fuzzer constructs a CopyOutResponse for an artificial table with >64k columns, or a mis-scoped loop appends format codes beyond the column count.
Related errors
- too many column format codes
- too many column format codes
- secret key too long
- too many values
- too many arg format codes
AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04).
Data as JSON: /data/errors/6d486e533580f912.json.
Report an issue: GitHub.