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
- Remove null-key entries from the JSON object before sending: every key must be a non-null value.
- Sanitize the decoded Map programmatically (filter entries with null keys) before calling fromJSONObject.
- 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
- Never emit entries with null keys in JSON objects
- Sanitize decoded maps: entries.removeIf(e -> e.getKey() == null)
- Use explicit sentinel keys instead of null placeholders in upstream data
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
- Invalid null value in map
- Expected a map, but got a %s: %s
- null is not supported inside collections
- Invalid null element in set
- Invalid null element in list
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/5a0c3c4c0ab88630.
Report an issue: GitHub.