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
- 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.
- 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.
- If you are building a server/proxy, enforce the 264-byte cap at the framing boundary and close connections that announce larger cancel bodies.
- 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
- Enforce the 264-byte cap at the framing boundary and close oversized connections.
- Log the declared length when a message seems oversized — a huge value usually means a corrupt length prefix.
- Do not concatenate multiple messages into one buffer before decoding.
- Forward raw bytes in proxies instead of re-encoding.
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
- cancel request too short
- bad cancel request code
- secret key too long
- gss encoding request too short
- too many column format codes
AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04).
Data as JSON: /data/errors/9e9641b539b14919.json.
Report an issue: GitHub.