jackc/pgx · error

cancel request too long

Error message

cancel request too long

What it means

Returned by CancelRequest.Decode when the input exceeds 264 bytes. The cancel request body is capped at 8 header bytes plus a 256-byte secret key, matching the maximum the PostgreSQL server will accept. Anything larger indicates either a corrupt length prefix or a non-conformant sender, so the library rejects it to avoid unbounded allocation.

Source

Thrown at pgproto3/cancel_request.go:27

	"github.com/jackc/pgx/v5/internal/pgio"
)

const cancelRequestCode = 80877102

type CancelRequest struct {
	ProcessID uint32
	SecretKey []byte
}

// Frontend identifies this message as sendable by a PostgreSQL frontend.
func (*CancelRequest) Frontend() {}

func (dst *CancelRequest) Decode(src []byte) error {
	if len(src) < 12 {
		return errors.New("cancel request too short")
	}
	if len(src) > 264 {
		return errors.New("cancel request too long")
	}

	requestCode := binary.BigEndian.Uint32(src)
	if requestCode != cancelRequestCode {
		return errors.New("bad cancel request code")
	}

	dst.ProcessID = binary.BigEndian.Uint32(src[4:])
	dst.SecretKey = make([]byte, len(src)-8)
	copy(dst.SecretKey, src[8:])

	return nil
}

// Encode encodes src into dst. dst will include the 4 byte message length.
func (src *CancelRequest) Encode(dst []byte) ([]byte, error) {
	if len(src.SecretKey) > 256 {
		return nil, errors.New("secret key too long")

View on GitHub (pinned to ec1a0befd2)

Solutions

  1. Confirm the framing layer (Frontend.Receive or your manual length-prefix parser) stripped the correct 4-byte length and handed only the declared body to Decode.
  2. Log the actual `len(src)` — if it is enormous, the real bug is a bad length prefix or a misrouted message upstream, not the cancel decoder.
  3. If you are building a server/proxy, enforce the 264-byte cap at the framing boundary and close connections that announce larger cancel bodies.
  4. Check the sender is not appending trailing bytes (e.g. a stray NUL or a second message concatenated).

Example fix

// before
err := cr.Decode(body) // body is 400 bytes because the length prefix was misread

// after
if len(body) > 264 {
    return fmt.Errorf("oversized cancel body: %d bytes (max 264)", len(body))
}
err := cr.Decode(body)
Defensive patterns

Strategy: validation

Validate before calling

const maxCancelRequestBodyLen = 264

func validateCancelRequestMaxLen(src []byte) error {
	if len(src) > maxCancelRequestBodyLen {
		return fmt.Errorf("cancel request body too long: %d bytes (max %d)", len(src), maxCancelRequestBodyLen)
	}
	return nil
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: `(*CancelRequest).Decode(src)` is called with `len(src) > 264`. Occurs on the receiving side of a cancel request (server, proxy, test harness) when the framed body is oversized.

Common situations: A corrupted length field upstream causes a huge buffer to be handed to Decode. Also seen when a bug in a proxy forwards the wrong message type into the cancel-request decoder, or when a fuzzed input produces a massively oversized payload.

Related errors


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