{"id":"5b79d03c63bd8fa9","repo":"jackc/pgx","slug":"insufficient-bytes","errorCode":null,"errorMessage":"insufficient bytes","messagePattern":"insufficient bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pgio/read.go","lineNumber":12,"sourceCode":"package pgio\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n)\n\n// ErrInsufficientBytes is wrapped by all Reader errors caused by a read past\n// the end of the source.\nvar ErrInsufficientBytes = errors.New(\"insufficient bytes\")\n\n// Reader is a bounds-checked reader for the PostgreSQL binary format. It is\n// designed so that decoders of untrusted input cannot forget a length check:\n// every read validates against the remaining bytes, and the first failure\n// sticks. After a failure all subsequent reads return zero values, so a\n// decoder can read an entire structure without intermediate error checks and\n// inspect Err or Finish once at the end.\n//\n// Reads never panic. A decoder that branches on a value it just read (e.g. an\n// element count used to size an allocation) should check Err before acting on\n// the value.\ntype Reader struct {\n\ts   []byte\n\trp  int\n\terr error\n}\n\nfunc NewReader(s []byte) *Reader {","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/internal/pgio/read.go#L1-L30","documentation":"ErrInsufficientBytes is the sentinel (internal/pgio/read.go:12) wrapped by every bounds-check failure in the pgio.Reader — a fixed-size read (Byte/Uint16/…/Int64), Bytes(n), CString (unterminated), or Count (count exceeds remaining) tried to advance past the end of the source byte slice. It surfaces from a pgtype Codec decoding a PostgreSQL binary value whose wire bytes are shorter than the type's layout requires.","triggerScenarios":"Decoding a binary-format value whose payload is truncated: a corrupted/too-short binary column, a server/extension sending malformed data, a codec reading a field the message did not include, or a hand-rolled codec that over-reads. Also from CString on a non-NUL-terminated string.","commonSituations":"A column of a custom or extension type whose binary format pgx's codec parses incorrectly (version skew); a network/proxy truncating messages; a corrupted pg_dump/restore; an extension returning an unexpected payload shape; a hand-written Codec that mis-sizes reads.","solutions":["If it reproduces on a specific column, capture the raw bytes and confirm the server is sending the documented binary format for that type OID.","Update pgx and any pgtype-related extensions to match the PostgreSQL server version (codec/server version skew is the most common cause).","For custom codecs, audit reads to match the documented layout; prefer pgio.Reader over manual slicing so bounds are checked.","Check the column's typname/typreceive to ensure you are using the right codec; register the correct type if a default fallback is mis-decoding.","Inspect network/proxy (PgBouncer in non-session-pooling modes, a truncating proxy) if the bytes arrive short."],"exampleFix":"// before (custom codec over-reading)\nfunc (c *MyCodec) DecodeBinary(m *pgtype.Map, src []byte) (any, error) {\n    return binary.BigEndian.Uint32(src[:4]), nil // panics or wrong if src<4\n}\n\n// after — use pgio.Reader, surface ErrInsufficientBytes cleanly\nfunc (c *MyCodec) DecodeBinary(m *pgtype.Map, src []byte) (any, error) {\n    r := pgio.NewReader(src)\n    v := r.Uint32()\n    return v, r.Err()\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isInsufficientBytes(err error) bool { return errors.Is(err, pgio.ErrInsufficientBytes) }","tryCatchPattern":"v, err := codec.DecodeBinary(typeMap, src)\nif errors.Is(err, pgio.ErrInsufficientBytes) {\n    // truncated/corrupt payload; log OID + len(src) and drop/skip\n    log.Printf(\"short binary payload for oid=%d len=%d\", oid, len(src))\n    return nil, err\n}","preventionTips":["Keep pgx and type-extension versions aligned with the server.","Prefer pgio.Reader in custom codecs so bounds are checked.","Inspect corrupt OIDs/columns to pinpoint codec/server skew.","Rule out truncating proxies (PgBouncer, custom middleware)."],"tags":["decode","binary-protocol","corruption","pgio"],"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","schemaVersion":2}