apache/cassandra · error · MarshalException

Invalid null key in map

Error message

Invalid null key in map

What it means

When building map Terms from JSON, MapType.fromJSONObject() iterates the decoded Map's entries and rejects any entry whose key is null. JSON decoding can yield null keys (e.g. JSON null key or a decoded map containing a null key), and Cassandra maps cannot contain null keys, so MarshalException is thrown.

Source

Thrown at src/java/org/apache/cassandra/db/marshal/MapType.java:347

        return bbs;
    }

    @Override
    public Term fromJSONObject(Object parsed) throws MarshalException
    {
        if (parsed instanceof String)
            parsed = JsonUtils.decodeJson((String) parsed);

        if (!(parsed instanceof Map))
            throw new MarshalException(String.format(
                    "Expected a map, but got a %s: %s", parsed.getClass().getSimpleName(), parsed));

        Map<?, ?> map = (Map<?, ?>) parsed;
        List<Term> terms = new ArrayList<>(map.size() << 1);
        for (Map.Entry<?, ?> entry : map.entrySet())
        {
            if (entry.getKey() == null)
                throw new MarshalException("Invalid null key in map");

            if (entry.getValue() == null)
                throw new MarshalException("Invalid null value in map");

            terms.add(keys.fromJSONObject(entry.getKey()));
            terms.add(values.fromJSONObject(entry.getValue()));
        }
        return new MultiElements.DelayedValue(this, terms);
    }

    @Override
    public String toJSONString(ByteBuffer buffer, ProtocolVersion protocolVersion)
    {
        ByteBuffer value = buffer.duplicate();
        StringBuilder sb = new StringBuilder("{");
        int size = CollectionSerializer.readCollectionSize(value, ByteBufferAccessor.instance);
        int offset = CollectionSerializer.sizeOfCollectionSize();
        for (int i = 0; i < size; i++)

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Remove null-key entries from the JSON object before sending: every key must be a non-null value.
  2. Sanitize the decoded Map programmatically (filter entries with null keys) before calling fromJSONObject.
  3. Catch MarshalException and report which map field contains a null key to the caller.

Example fix

// before
{"m": {"a": 1, null: 2}}
// after
{"m": {"a": 1, "b": 2}}
Defensive patterns

Strategy: validation

Validate before calling

Map<?,?> map = (Map<?,?>) decoded;
if (map.keySet().stream().anyMatch(Objects::isNull))
    throw new IllegalArgumentException("map contains a null key");

Try / catch

try {
    Term term = mapType.fromJSONObject(parsed);
} catch (MarshalException e) {
    if (e.getMessage().contains("null key")) {
        // strip null-key entries or reject record
    }
}

Prevention

When it happens

Trigger: Calling fromJSONObject on MapType with a Map that contains a null key — typically from JSON like {"m": {"null": null}} decoded with a null key entry, or programmatically constructed maps with null keys.

Common situations: JSON ingestion pipelines producing maps with null keys; client libraries emitting {'key': null} entries; deserializers that map JSON null placeholders to Java null keys.

Related errors


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