prestodb/presto · error · IllegalStateException

Map key is null at position: " + position

Error message

Map key is null at position: " + position

What it means

When reading position 0 (even position = the key slot) of a single-map block, AbstractSingleMapBlock.isNull checks the key block. A null key inside a map is illegal in Presto's map semantics, so the library throws IllegalStateException rather than reporting isNull=true for the key position.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/AbstractSingleMapBlock.java:45

    abstract Block getRawKeyBlock();

    abstract Block getRawValueBlock();

    private int getAbsolutePosition(int position)
    {
        if (position < 0 || position >= getPositionCount()) {
            throw new IllegalArgumentException("position is not valid: " + position);
        }
        return position + getOffset();
    }

    @Override
    public boolean isNull(int position)
    {
        position = getAbsolutePosition(position);
        if (position % 2 == 0) {
            if (getRawKeyBlock().isNull(position / 2)) {
                throw new IllegalStateException("Map key is null at position: " + position);
            }
            return false;
        }
        else {
            return getRawValueBlock().isNull(position / 2);
        }
    }

    @Override
    public byte getByte(int position)
    {
        return getByteUnchecked(getAbsolutePosition(position));
    }

    @Override
    public short getShort(int position)
    {
        return getShortUnchecked(getAbsolutePosition(position));

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Enforce non-null keys when building maps: filter out or reject rows with null keys before constructing the map block.
  2. If data is already corrupted, re-validate with map_null_key_reraise / map constructor checks or rebuild the block with null keys removed.
  3. Trace the producer of the block and fix it to use the standard MapBuilder, which rejects null keys.

Example fix

// before
keyBlockBuilder.appendNull(); // null map key
valueBlockBuilder.appendLong(v);
// after
if (keyIsNull) {
    throw new InvalidCastException("map key cannot be null");
}
keyBlockBuilder.appendLong(key);
valueBlockBuilder.appendLong(v);
Defensive patterns

Strategy: validation

Validate before calling

static Block ensureNoNullKeys(MapType mapType, Block rawKeyBlock, int keyCount) {
    for (int i = 0; i < keyCount; i++) {
        if (rawKeyBlock.isNull(i)) {
            throw new IllegalStateException("map key is null at " + i);
        }
    }
    return rawKeyBlock;
}

Try / catch

try {
    boolean isNull = singleMapBlock.isNull(position);
} catch (IllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().contains("Map key is null")) {
        throw new DataCorruptionException("map contains a null key", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Reading a map block whose underlying key block contains a null at the key position — produced by code that built the map without enforcing non-null keys (e.g. a connector or function writing null keys), then accessed via isNull/element getters.

Common situations: UDFs or connectors constructing maps from user data containing null keys; missing validation between map construction (which normally rejects null keys) and a block assembled through the low-level single-map path.

Related errors


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