jackc/pgx · error

too many values

Error message

too many values

What it means

Returned by DataRow.Encode when the Values slice has more than 65535 entries. The field count is encoded as a uint16, so MaxUint16 is the hard ceiling. The guard prevents a silently-truncated count that would make the receiver misread the row. DataRow is the 'D' message carrying one row's column values.

Source

Thrown at pgproto3/data_row.go:69

		} else {
			if len(src[rp:]) < valueLen || valueLen < 0 {
				return &invalidMessageFormatErr{messageType: "DataRow"}
			}

			dst.Values[i] = src[rp : rp+valueLen : rp+valueLen]
			rp += valueLen
		}
	}

	return nil
}

// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
func (src *DataRow) Encode(dst []byte) ([]byte, error) {
	dst, sp := beginMessage(dst, 'D')

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

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

	return finishMessage(dst, sp)
}

// MarshalJSON implements encoding/json.Marshaler.
func (src DataRow) MarshalJSON() ([]byte, error) {
	formattedValues := make([]map[string]string, len(src.Values))

View on GitHub (pinned to ec1a0befd2)

Solutions

  1. Bound the Values slice to 65535 entries before encoding; if you genuinely have more, the wire protocol cannot carry it in one DataRow.
  2. Audit the loop that builds Values for accidental duplication or mis-scoping.
  3. If serialising a struct/map, cap or chunk the columns and reconsider the schema (PostgreSQL itself limits columns to ~1600 per table).
  4. Add a pre-encode length check returning a clear error to the caller.

Example fix

// before
row := &pgproto3.DataRow{Values: allValues} // len > 65535
_, err := row.Encode(nil)

// after
if len(allValues) > 65535 {
    return fmt.Errorf("too many columns: %d (max 65535)", len(allValues))
}
row := &pgproto3.DataRow{Values: allValues}
_, err := row.Encode(nil)
Defensive patterns

Strategy: validation

Validate before calling

func validateDataRowEncode(r *pgproto3.DataRow) error {
	if len(r.Values) > math.MaxUint16 {
		return fmt.Errorf("too many values: %d (max %d)", len(r.Values), math.MaxUint16)
	}
	return nil
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Calling `(*DataRow).Encode(dst)` with `len(Values) > 65535`. This is a client→server message in the extended-query path, so it can be hit by application code constructing a row with an enormous column count.

Common situations: A caller loops over a map or struct and appends one value per key without bounding the count, or a bug duplicates entries. Real-world tables almost never have >64k columns, so this usually signals a construction bug rather than a legitimate wide row.

Related errors


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