prestodb/presto · error · IllegalArgumentException

Deserialized MapBlock violates invariants: key %d, value %d

Error message

Deserialized MapBlock violates invariants: key %d, value %d

What it means

readBlock deserializes a MapBlock from a SliceInput and verifies structural invariants; the key and value blocks must have equal position counts because each key maps 1:1 to a value. A mismatch means the serialized payload is corrupt, truncated, or was produced by an incompatible writer, so readBlock throws IllegalArgumentException.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/MapBlockEncoding.java:87

        }
        EncoderUtil.encodeNullsAsBits(sliceOutput, block);
    }

    @Override
    public Block readBlock(BlockEncodingSerde blockEncodingSerde, SliceInput sliceInput)
    {
        Block keyBlock = blockEncodingSerde.readBlock(sliceInput);
        Block valueBlock = blockEncodingSerde.readBlock(sliceInput);

        int hashTableLength = sliceInput.readInt();
        int[] hashTable = null;
        if (hashTableLength >= 0) {
            hashTable = new int[hashTableLength];
            sliceInput.readBytes(wrappedIntArray(hashTable));
        }

        if (keyBlock.getPositionCount() != valueBlock.getPositionCount()) {
            throw new IllegalArgumentException(
                    format("Deserialized MapBlock violates invariants: key %d, value %d", keyBlock.getPositionCount(), valueBlock.getPositionCount()));
        }

        if (hashTable != null && keyBlock.getPositionCount() * HASH_MULTIPLIER != hashTable.length) {
            throw new IllegalArgumentException(
                    format("Deserialized MapBlock violates invariants: expected hashtable size %d, actual hashtable size %d", keyBlock.getPositionCount() * HASH_MULTIPLIER, hashTable.length));
        }

        int positionCount = sliceInput.readInt();
        int[] offsets = new int[positionCount + 1];
        sliceInput.readBytes(wrappedIntArray(offsets));
        Optional<boolean[]> mapIsNull = EncoderUtil.decodeNullBits(sliceInput, positionCount);
        return MapType.createMapBlockInternal(0, positionCount, mapIsNull, offsets, keyBlock, valueBlock, new HashTables(Optional.ofNullable(hashTable), positionCount));
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Verify integrity of the serialized data source (checksums, exchange retry)
  2. Ensure all nodes run compatible Presto versions (same block encoding format)
  3. Re-fetch the block from the origin instead of using the corrupt payload
Defensive patterns

Strategy: try-catch

Try / catch

try {
    Block block = blockEncoding.readBlock(sliceInput);
} catch (IllegalArgumentException e) {
    // log corrupt payload, re-fetch from origin, alert on checksum mismatch
}

Prevention

When it happens

Trigger: Reading a MapBlock from serialized bytes where the encoded keyBlock has a different positionCount than the encoded valueBlock — corrupted network/storage payload, wrong offsets, or version mismatch between serializer and deserializer.

Common situations: Exchange or spill data corrupted in transit; a Presto version skew where block encoding changed; bugs in custom block writers.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/2f881477f668da04. Report an issue: GitHub.