jackc/pgx · error

element count at offset exceeds remaining bytes

Error message

element count %d at offset %d exceeds %d remaining bytes

What it means

Reader.Count determined the claimed element count times the minimum element size exceeds the bytes remaining in the message — a length/count combination impossible to satisfy, typical of a corrupt or hostile message trying to induce a huge allocation.

Solutions

  1. Treat the message as corrupt and close the connection
  2. Verify the count field and message length agree in the encoder
  3. Check for middleware or proxies mangling the byte stream
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at internal/pgio/read.go:169 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at internal/pgio/read.go:169

// bytes: the count must be non-negative, and since each element occupies at
// least minElemSize bytes, count*minElemSize must not exceed the remaining
// message. This bounds allocations sized from the count against a malicious
// or corrupt message claiming a huge count. Returns 0 on any failure.
func (r *Reader) Count(minElemSize int) int {
	offset := r.rp
	count := int(r.Int32())
	if r.err != nil {
		return 0
	}
	if count < 0 {
		r.fail(fmt.Errorf("invalid element count %d at offset %d", count, offset))
		return 0
	}
	if minElemSize < 1 {
		minElemSize = 1
	}
	if count > r.Remaining()/minElemSize {
		r.fail(fmt.Errorf("element count %d at offset %d exceeds %d remaining bytes", count, offset, r.Remaining()))
		return 0
	}
	return count
}

// Value reads an int32 length followed by that many bytes — the standard
// PostgreSQL binary representation of a value. A length of -1 means NULL and
// returns (nil, true). Any other negative length is an error. The returned
// slice aliases the source; null is only meaningful if Err returns nil.
func (r *Reader) Value() (data []byte, null bool) {
	offset := r.rp
	length := r.Int32()
	if r.err != nil {
		return nil, false
	}
	if length == -1 {
		return nil, true
	}

View on GitHub (pinned to ec1a0befd2)