{"record":{"id":"fdb2851bd61f18dd","repo":"prestodb/presto","slug":"deserialized-mapblock-violates-invariants-expecte","errorCode":null,"errorMessage":"Deserialized MapBlock violates invariants: expected hashtable size %d, actual hashtable size %d","messagePattern":"Deserialized MapBlock violates invariants: expected hashtable size (.+?), actual hashtable size (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/MapBlockEncoding.java","lineNumber":92,"sourceCode":"    public Block readBlock(BlockEncodingSerde blockEncodingSerde, SliceInput sliceInput)\n    {\n        Block keyBlock = blockEncodingSerde.readBlock(sliceInput);\n        Block valueBlock = blockEncodingSerde.readBlock(sliceInput);\n\n        int hashTableLength = sliceInput.readInt();\n        int[] hashTable = null;\n        if (hashTableLength >= 0) {\n            hashTable = new int[hashTableLength];\n            sliceInput.readBytes(wrappedIntArray(hashTable));\n        }\n\n        if (keyBlock.getPositionCount() != valueBlock.getPositionCount()) {\n            throw new IllegalArgumentException(\n                    format(\"Deserialized MapBlock violates invariants: key %d, value %d\", keyBlock.getPositionCount(), valueBlock.getPositionCount()));\n        }\n\n        if (hashTable != null && keyBlock.getPositionCount() * HASH_MULTIPLIER != hashTable.length) {\n            throw new IllegalArgumentException(\n                    format(\"Deserialized MapBlock violates invariants: expected hashtable size %d, actual hashtable size %d\", keyBlock.getPositionCount() * HASH_MULTIPLIER, hashTable.length));\n        }\n\n        int positionCount = sliceInput.readInt();\n        int[] offsets = new int[positionCount + 1];\n        sliceInput.readBytes(wrappedIntArray(offsets));\n        Optional<boolean[]> mapIsNull = EncoderUtil.decodeNullBits(sliceInput, positionCount);\n        return MapType.createMapBlockInternal(0, positionCount, mapIsNull, offsets, keyBlock, valueBlock, new HashTables(Optional.ofNullable(hashTable), positionCount));\n    }\n}\n","sourceCodeStart":74,"sourceCodeEnd":103,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/MapBlockEncoding.java#L74-L103","documentation":"readBlock additionally checks that the optional hash table, when present, has exactly positionCount * HASH_MULTIPLIER entries, as Presto's map hash tables are sized by a fixed multiplier of the entry count. Any other length indicates a corrupt or hand-crafted serialized block and throws IllegalArgumentException.","triggerScenarios":"Deserializing a MapBlock whose hashTableLength field is nonzero and != keyBlock.getPositionCount() * HASH_MULTIPLIER — corrupted slice, misaligned read offsets, or writer/deserializer version mismatch.","commonSituations":"Bytes shifted by an earlier misread field; incompatible wire format across Presto versions; manual manipulation of serialized block data in tests.","solutions":["Re-acquire the serialized block and retry the transfer","Align Presto versions across the cluster so encoding formats match","Add checksum validation on the transfer channel that carries block bytes"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    Block block = blockEncoding.readBlock(sliceInput);\n} catch (IllegalArgumentException e) {\n    // treat as corrupt payload: retry transfer or recompute\n}","preventionTips":["Validate slice offsets/lengths before deserialization","Verify HASH_MULTIPLIER-based table sizing in custom writers","Add integration tests covering serialized round-trips"],"tags":["deserialization","map-block","hash-table","data-corruption"],"backgroundTag":"deserialization-invariant-violated","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}