apache/cassandra · error · InvalidRequestException

Invalid null map key for column

Error message

Invalid null map key for column %s

What it means

Thrown by SimpleRestriction.addToRowFilter when a map-column restriction (e.g. `WHERE m[?] = x` or CONTAINS KEY) resolves its map key element to null. Cassandra rejects null map keys because a null key cannot participate in row filtering or map equality lookups.

Solutions

  1. Check the value bound to the map key placeholder and substitute a non-null key before executing.
  2. If the key comes from external input, validate it is non-null and reject the request client-side with a clear message.
  3. If the intent is a key-less containment check, use CONTAINS on values instead of a map-key (CONTAINS KEY) restriction.
  4. Use UNSET awareness in drivers: distinguish unset from null and skip the restriction entirely when the key was not provided.

Example fix

// before
stmt.bind(Map.of("key", requestedKey)); // requestedKey may be null
// after
if (requestedKey == null)
    throw new IllegalArgumentException("map key must be provided");
stmt.bind(Map.of("key", requestedKey));
Defensive patterns

Strategy: validation

Validate before calling

if (mapKey == null) throw new IllegalArgumentException("map key must be non-null for WHERE m[key] restriction");

Prevention

When it happens

Trigger: Executing a CQL statement with a map key restriction whose bound key variable is bound to null, or an expression (e.g. a function/UDF or JSON value) that evaluates to null for the map element, e.g. `SELECT * FROM t WHERE m[null] = 1` or binding null to the key placeholder of `m[?] = ?`.

Common situations: Application code binds a null value into the key position of a map restriction; deserialized/JSON input omits the key so it arrives as null; a UDF or collection-access expression returns null instead of a key.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/bcbefd4dc63fcfe5. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/restrictions/SimpleRestriction.java:456

                {
                    // For frozen maps, check if any index on the column can support map entry predicates
                    // either directly or via filtering. If not, throw an error.
                    if (column.type.isFrozenCollection())
                    {
                        for (Index index : indexRegistry.listIndexes())
                        {
                            if (index.dependsOn(column)
                                && !index.supportsMapElementExpression()
                                && !index.supportsFilteringOnMapElementExpression())
                            {
                                throw invalidRequest(Relation.FROZEN_MAP_ENTRY_PREDICATES_NOT_SUPPORTED, column.name);
                            }
                        }
                    }

                    ByteBuffer key = columnsExpression.element(context);
                    if (key == null)
                        throw invalidRequest("Invalid null map key for column %s", column.name.toCQLString());
                    if (key == ByteBufferUtil.UNSET_BYTE_BUFFER)
                        throw invalidRequest("Invalid unset map key for column %s", column.name.toCQLString());
                    List<ByteBuffer> values = bindAndGet(context);
                    filter.addMapEquality(column, key, operator, values.get(0));
                }
                break;
            default: throw new UnsupportedOperationException();
        }
    }

    private static ByteBuffer multiInputOperatorValues(ColumnMetadata column, List<ByteBuffer> values)
    {
        return ListType.getInstance(column.type, false).pack(values);
    }

    @Override
    public String toString()
    {

View on GitHub (pinned to 88fd0f6a0e)