apache/cassandra · error · MarshalException

Null value read when not allowed

Error message

Null value read when not allowed

What it means

readNonNullValue reads one collection element and rejects nulls. Collection elements are length-prefixed with -1 encoding null; collections in Cassandra do not permit null elements, so a null element read is treated as invalid data and MarshalException is thrown.

Source

Thrown at src/java/org/apache/cassandra/serializers/CollectionSerializer.java:181

        output.putInt(accessor.size(value));
        accessor.write(value, output);
    }

    public static <V> V readValue(V input, ValueAccessor<V> accessor, int offset)
    {
        int size = accessor.getInt(input, offset);
        if (size < 0)
            return null;

        return accessor.slice(input, offset + TypeSizes.INT_SIZE, size);
    }

    public static <V> V readNonNullValue(V input, ValueAccessor<V> accessor, int offset)
    {
        V value = readValue(input, accessor, offset);
        if (value == null)
            throw new MarshalException("Null value read when not allowed");
        return value;
    }

    protected static void skipValue(ByteBuffer input)
    {
        int size = input.getInt();
        input.position(input.position() + size);
    }

    public static <V> int skipValue(V input, ValueAccessor<V> accessor, int offset)
    {
        int size = accessor.getInt(input, offset);
        return TypeSizes.sizeof(size) + size;
    }

    public static <V> int sizeOfValue(V value, ValueAccessor<V> accessor)
    {
        return value == null ? 4 : 4 + accessor.size(value);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Remove or rewrite the offending null element in the data
  2. In custom serialization, skip null elements instead of encoding them (use readValue and check for null)
  3. Use fully-assembled collections in application code, never null members
  4. If data is on disk, scrub/repair or migrate the affected rows

Example fix

// before
V v = CollectionSerializer.readNonNullValue(input, accessor, offset); // throws on null
// after
V v = CollectionSerializer.readValue(input, accessor, offset);
if (v == null) { v = defaultValue; }
Defensive patterns

Strategy: validation

Validate before calling

public static boolean hasNullElements(ByteBuffer collectionBuf, AbstractType<?> elementType) {
    ByteBuffer dup = collectionBuf.duplicate();
    int n = dup.getInt();
    for (int i = 0; i < n; i++) {
        int size = dup.getInt();
        if (size < 0) return true;
        dup.position(dup.position() + size);
    }
    return false;
}

Type guard

public static boolean isNonNullElement(ByteBuffer element) {
    return element != null && element.remaining() >= 0;
}

Try / catch

try {
    serializer.validate(buffer, accessor);
} catch (MarshalException e) {
    logger.warn("Collection contains a null element: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Iterating a collection's elements where an element's length prefix is -1 — e.g. a map/list containing a null value inserted via a driver that allowed it, or bytes built manually with a null element marker.

Common situations: Legacy or corrupted data containing null collection members; custom serialization code writing -1 lengths; driver/UDF code inserting nulls into lists/sets/maps before validation was enforced.

Related errors


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