apache/cassandra · error · MarshalException

Invalid null value in map

Error message

Invalid null value in map

What it means

MapType.fromJSONObject() rejects any map entry whose value is null, since Cassandra collection values cannot be null. Each decoded entry's value is checked before element terms are built; a null value raises MarshalException.

Source

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

    @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++)
        {
            if (i > 0)
                sb.append(", ");

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Remove keys with null values from the JSON object, or set explicit non-null values.
  2. Use a DELETE/UNSET statement for removal semantics instead of sending null values.
  3. Filter null values from the decoded Map before calling fromJSONObject.

Example fix

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

Strategy: validation

Validate before calling

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

Try / catch

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

Prevention

When it happens

Trigger: Calling fromJSONObject on MapType with a decoded Map containing a null value — e.g. JSON like {"m": {"a": null}}.

Common situations: Client code emitting JSON null for absent values instead of omitting the key; ingestion pipelines preserving nulls from upstream data; partial updates expressed as nulls in map fields.

Related errors


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