{"record":{"id":"46b1fd849a5cf62c","repo":"transact-rs/sqlx","slug":"varbit-length-mismatch","errorCode":null,"errorMessage":"VARBIT length mismatch.","messagePattern":"VARBIT length mismatch\\.","errorType":"exception","errorClass":"io::Error (InvalidData)","httpStatus":null,"severity":"error","filePath":"sqlx-postgres/src/types/bit_vec.rs","lineNumber":61,"sourceCode":"    fn size_hint(&self) -> usize {\n        mem::size_of::<i32>() + self.len()\n    }\n}\n\nimpl Decode<'_, Postgres> for BitVec {\n    fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {\n        match value.format() {\n            PgValueFormat::Binary => {\n                let mut bytes = value.as_bytes()?;\n                let len = bytes.get_i32();\n\n                let len = usize::try_from(len).map_err(|_| format!(\"invalid VARBIT len: {len}\"))?;\n\n                // The smallest amount of data we can read is one byte\n                let bytes_len = len.div_ceil(8);\n\n                if bytes.remaining() != bytes_len {\n                    Err(io::Error::new(\n                        io::ErrorKind::InvalidData,\n                        \"VARBIT length mismatch.\",\n                    ))?;\n                }\n\n                let mut bitvec = BitVec::from_bytes(bytes);\n\n                // Chop off zeroes from the back. We get bits in bytes, so if\n                // our bitvec is not in full bytes, extra zeroes are added to\n                // the end.\n                while bitvec.len() > len {\n                    bitvec.pop();\n                }\n\n                Ok(bitvec)\n            }\n            PgValueFormat::Text => {\n                let s = value.as_str()?;","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/transact-rs/sqlx/blob/03af8bcc5711a1935580a54bea249c219a0c217d/sqlx-postgres/src/types/bit_vec.rs#L43-L79","documentation":"Postgres VARBIT/BIT values are decoded by reading the declared bit length and computing the expected byte count (`len.div_ceil(8)`). If the wire buffer's remaining bytes don't exactly match that count, the payload is malformed, and decoding fails with `InvalidData` and 'VARBIT length mismatch.'.","triggerScenarios":"Decoding a BIT/VARBIT column whose received payload length disagrees with its declared bit length — corrupted/truncated result data, or a custom/proxy server emitting a non-conforming wire format.","commonSituations":"Bit column written by another tool with an inconsistent length prefix; values produced through an intermediate server or driver with a wire-format bug; manually hand-crafted test fixtures with wrong byte counts.","solutions":["Verify the column type and data with psql (`SELECT bit_length(col), col FROM ...`) to confirm server-side integrity","Re-insert or recompute the affected BIT/VARBIT values if data is corrupted","Remove/fix any proxy or custom protocol layer mangling the BIT payload","If you control encoding, ensure the payload is exactly `ceil(len/8)` bytes for the declared bit length"],"exampleFix":"// before: fixture with mismatched declared length vs bytes\nlet value: BitVec = sqlx::decode::decode(&[0u8, 9, 0xFF].encode()[..])?; // len=9 but 1 byte only? mismatch cases panic here\n// after: encode with matching length prefix\nlet bits = BitVec::from_slice(&[0b1111_1111, 0b1000_0000]);\nlet encoded = PgBitVec::encode(bits); // consistent len/bytes\n","handlingStrategy":"try-catch","validationCode":"// sanity-check length consistency before decoding raw bytes\nlet len = u32::from_be_bytes(raw[0..4].try_into().unwrap()) as usize;\nassert_eq!(raw.len() - 4, len.div_ceil(8), \"BIT payload length mismatch\");","typeGuard":null,"tryCatchPattern":"match row.try_get::<BitVec, _>(\"flags\") {\n    Ok(bits) => bits,\n    Err(e) if e.to_string().contains(\"VARBIT length mismatch\") => {\n        // log and inspect raw column data; treat row as corrupt\n        BitVec::new()\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Write BIT/VARBIT values only through sqlx or psql, not hand-rolled wire frames","Avoid intermediaries/proxies that rewrite result payloads","Validate affected columns after schema migrations or data imports","Add a round-trip encode/decode test for BIT columns in your test suite"],"tags":["rust","sqlx","postgres","decode","bit-vec","protocol"],"backgroundTag":"malformed-column-data","analyzedSha":"03af8bcc5711a1935580a54bea249c219a0c217d","analyzedAt":"2026-09-03T15:01:28.752Z","contentChangedAt":"2026-09-03T15:01:28.752Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}