jackc/pgx · error

too many result format codes

Error message

too many result format codes

What it means

Returned by Bind.Encode in pgproto3/bind.go:144 when len(src.ResultFormatCodes) exceeds 65535 (math.MaxUint16). The wire protocol encodes the result-format-code count as a uint16, so more than 65535 codes cannot be serialized. Fired client-side during Encode, before any network I/O. Since result format codes map to result columns, this also implies the query selects more than 65535 columns - itself far above PostgreSQL's real column limit.

Source

Thrown at pgproto3/bind.go:144

		dst = pgio.AppendInt16(dst, fc)
	}

	if len(src.Parameters) > math.MaxUint16 {
		return nil, errors.New("too many parameters")
	}
	dst = pgio.AppendUint16(dst, uint16(len(src.Parameters)))
	for _, p := range src.Parameters {
		if p == nil {
			dst = pgio.AppendInt32(dst, -1)
			continue
		}

		dst = pgio.AppendInt32(dst, int32(len(p)))
		dst = append(dst, p...)
	}

	if len(src.ResultFormatCodes) > math.MaxUint16 {
		return nil, errors.New("too many result format codes")
	}
	dst = pgio.AppendUint16(dst, uint16(len(src.ResultFormatCodes)))
	for _, fc := range src.ResultFormatCodes {
		dst = pgio.AppendInt16(dst, fc)
	}

	return finishMessage(dst, sp)
}

// MarshalJSON implements encoding/json.Marshaler.
func (src Bind) MarshalJSON() ([]byte, error) {
	formattedParameters := make([]map[string]string, len(src.Parameters))
	for i, p := range src.Parameters {
		if p == nil {
			continue
		}

		textFormat := true

View on GitHub (pinned to ec1a0befd2)

Solutions

  1. Cap ResultFormatCodes at 65535; for uniform result format use a single code (one code applies to all columns).
  2. Reduce the selected column count to what the application actually needs (SELECT explicit columns, not a generated superset).
  3. Validate column count against the protocol limit before issuing the query.

Example fix

// before: one result format code per column, exceeds 65535
resultFormats := make([]int16, numCols) // numCols > 65535 -> "too many result format codes"

// after: a single code applies to all result columns
resultFormats := []int16{1} // binary format for every column
Defensive patterns

Strategy: validation

Validate before calling

const maxResultFormatCodes = 65535 // math.MaxUint16
if len(resultFormatCodes) > maxResultFormatCodes {
    // Use a single code: the protocol applies one code to ALL result columns.
    resultFormatCodes = []int16{resultFormatCodes[0]}
}

Type guard

func bindResultFormatCodesOK(codes []int16) bool { return len(codes) <= 65535 }

Try / catch

if _, err := bindMsg.Encode(dst); err != nil {
    if strings.Contains(err.Error(), "too many result format codes") {
        bindMsg.ResultFormatCodes = []int16{bindMsg.ResultFormatCodes[0]}
    }
}

Prevention

When it happens

Trigger: Constructing a Bind with an explicit ResultFormatCodes slice longer than 65535, or a SELECT whose column count exceeds the limit. Almost always an application bug (pgx normally emits one code per result column or a single default code).

Common situations: Selecting a huge generated column set; copying a result column count into ResultFormatCodes in a loop without a cap; building a custom query tool that mirrors an oversized schema.

Related errors


AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04). Data as JSON: /data/errors/432ca20e7c3cb646.json. Report an issue: GitHub.