prestodb/presto · error · IllegalArgumentException
A null map must have zero entries
Error message
A null map must have zero entries
What it means
A MAP block whose isNull flag is set for a row must encode zero entries for that row (offsets[i+1] == offsets[i]). If a null map is declared but the offsets slice claims entries, the block would have key/value data for a null value, which is inconsistent, so the library throws IllegalArgumentException.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/AbstractMapBlock.java:488
{
return INSTANCE_SIZE + sizeOf(hashTables);
}
public void loadHashTables(int positionCount, int[] offsets, boolean[] mapIsNull, Block keyBlock, MethodHandle keyBlockHashCode)
{
int[] hashTables = new int[keyBlock.getPositionCount() * HASH_MULTIPLIER];
Arrays.fill(hashTables, -1);
verify(positionCount < offsets.length, "incorrect offsets size");
for (int i = 0; i < positionCount; i++) {
int keyOffset = offsets[i];
int keyCount = offsets[i + 1] - keyOffset;
if (keyCount < 0) {
throw new IllegalArgumentException(format("Offset is not monotonically ascending. offsets[%s]=%s, offsets[%s]=%s", i, offsets[i], i + 1, offsets[i + 1]));
}
if (mapIsNull != null && mapIsNull[i] && keyCount != 0) {
throw new IllegalArgumentException("A null map must have zero entries");
}
buildHashTable(
keyBlock,
keyOffset,
keyCount,
keyBlockHashCode,
hashTables,
keyOffset * HASH_MULTIPLIER,
keyCount * HASH_MULTIPLIER);
}
set(hashTables);
}
// This class intentionally does not implement hashcode and equals.
// Any class using Hashtables as a field (MapBlock, MapBlockBuilder) should not include this class's implementation as this is
// derived data. Only using KeyBlock hashcode/equals should suffice.
// This class has no immutable fields, which makes hashcode/equals error-prone.
}View on GitHub (pinned to 55bb57d202)
Solutions
- Ensure that whenever mapIsNull[i] is true, offsets[i+1] is set equal to offsets[i] before building the block.
- Recompute the offsets array from the same source of truth (the per-row entry counts and null flags) rather than patching them independently.
- Check serialization round-trips: null flags and offsets must be written/read from the same stream version.
- Validate before construction: for each i, (!null || entryCount == 0).
Example fix
// before mapIsNull[i] = true; // offsets[i+1] left at 3, leaving 2 entries for the null map // after mapIsNull[i] = true; offsets[i + 1] = offsets[i]; // null map must have zero entries
Defensive patterns
Strategy: validation
Validate before calling
static void validateNullMapOffsets(int[] offsets, boolean[] mapIsNull, int positionCount) {
for (int i = 0; i < positionCount; i++) {
if (mapIsNull != null && mapIsNull[i]) {
checkArgument(offsets[i + 1] == offsets[i], "null map at %d must have zero entries", i);
}
}
} Try / catch
try {
Block mapBlock = buildMapBlock(keys, values, offsets, mapIsNull);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("A null map must have zero entries")) {
throw new DataCorruptionException("null map row carries entries", e);
}
throw e;
} Prevention
- Set null flags and offsets from the same per-row computation loop.
- Never patch mapIsNull after offsets are finalized.
- Round-trip test serialization: rebuild and validate blocks after decode.
When it happens
Trigger: Creating a map block where mapIsNull[i] is true but offsets[i+1] - offsets[i] != 0; typically from custom block construction or deserialization that sets null flags independently of the offsets array.
Common situations: Custom serializers writing null flags and offsets separately; connector code reusing offsets arrays from a previous non-null batch while adding null flags; version-mismatched page deserialization.
Related errors
- Offset is not monotonically ascending. offsets[%s]=%s, offse
- position is not valid: " + position
- slice is null
- Number of fields in RowBlock must be positive
- position is not valid
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/1cfd48b3dad6b064.
Report an issue: GitHub.