{"record":{"id":"2e1cd1a45b9beef4","repo":"jackc/pgx","slug":"array-claims-d-elements-but-only-d-bytes-remain","errorCode":null,"errorMessage":"array claims %d elements but only %d bytes remain","messagePattern":"array claims (.+?) elements but only (.+?) bytes remain","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pgtype/array_codec.go","lineNumber":275,"sourceCode":"\t\toid:        oid,\n\t\tformatCode: format,\n\t}\n}\n\nfunc (c *ArrayCodec) decodeBinary(m *Map, arrayOID uint32, src []byte, array ArraySetter) error {\n\tr := pgio.NewReader(src)\n\tvar arrayHeader arrayHeader\n\terr := arrayHeader.DecodeBinary(r)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\telementCount := cardinality(arrayHeader.Dimensions)\n\t// Each element carries at minimum a 4-byte length header, so elementCount cannot exceed the\n\t// remaining bytes / 4. This bounds the allocation in SetDimensions and the loop below against a\n\t// malicious server claiming huge dimensions in a small message.\n\tif maxElements := r.Remaining() / 4; elementCount > maxElements {\n\t\treturn fmt.Errorf(\"array claims %d elements but only %d bytes remain\", elementCount, r.Remaining())\n\t}\n\n\terr = array.SetDimensions(arrayHeader.Dimensions)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif elementCount == 0 {\n\t\treturn r.Finish()\n\t}\n\n\telementScanPlan := c.ElementType.Codec.PlanScan(m, c.ElementType.OID, BinaryFormatCode, array.ScanIndex(0))\n\tif elementScanPlan == nil {\n\t\telementScanPlan = m.PlanScan(c.ElementType.OID, BinaryFormatCode, array.ScanIndex(0))\n\t}\n\n\tfor i := range elementCount {\n\t\telem := array.ScanIndex(i)","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/pgtype/array_codec.go#L257-L293","documentation":"Binary array decode guard: the array header's dimensions claim more elements than could possibly fit in the remaining message bytes (each element needs at least a 4-byte length). This indicates a corrupt or malicious server response, and the check bounds allocations before SetDimensions.","triggerScenarios":"Thrown at pgtype/array_codec.go:275 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Treat the connection/data as untrusted and fail the query; do not retry the same payload","Check for a proxy or middleware corrupting binary results","Verify the server is a real PostgreSQL-compatible server sending well-formed binary arrays"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}