apache/cassandra · error · MarshalException

Element at index %d is null (expected type %s); given %s

Error message

Element at index %d is null (expected type %s); given %s

What it means

After the size check, check(List<?>) iterates the elements and throws MarshalException if any element is null (or a null-equivalent ByteBuffer), reporting the offending index and expected element type. Vectors cannot contain null elements.

Source

Thrown at src/java/org/apache/cassandra/db/marshal/VectorType.java:373

    }

    @Override
    public String toString(boolean ignoreFreezing)
    {
        return getClass().getName() + TypeParser.stringifyVectorParameters(elementType, ignoreFreezing, dimension);
    }

    private void check(List<?> values)
    {
        if (values.size() != dimension)
            throw new MarshalException(String.format("Required %d elements, but saw %d", dimension, values.size()));

        // This code base always works with a list that is RandomAccess, so can use .get to avoid allocation
        for (int i = 0; i < dimension; i++)
        {
            Object value = values.get(i);
            if (value == null || (value instanceof ByteBuffer && elementSerializer.isNull((ByteBuffer) value)))
                throw new MarshalException(String.format("Element at index %d is null (expected type %s); given %s", i, elementType.asCQL3Type(), values));
        }
    }

    private <V> void checkConsumedFully(V buffer, ValueAccessor<V> accessor, int offset)
    {
        int remaining = accessor.sizeFromOffset(buffer, offset);
        if (remaining > 0)
            throw new MarshalException("Unexpected " + remaining + " extraneous bytes after " + asCQL3Type() + " value");
    }
    
    private static void rejectNullOrEmptyValue()
    {
        throw new MarshalException("Invalid empty vector value");
    }

    @Override
    public ByteBuffer getMaskedValue()
    {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Ensure every element in the list is non-null before executing the statement
  2. Default or skip null elements before composing the vector
  3. Add a pre-execution validation that scans the list for nulls

Example fix

// before
List<Integer> elems = Arrays.asList(1, null, 3);
stmt = session.prepare("INSERT INTO t (v) VALUES (?)")...bind(elems);
// after
elems.set(1, 0); // or reject the record
stmt = session.prepare("INSERT INTO t (v) VALUES (?)")...bind(elems);
Defensive patterns

Strategy: validation

Validate before calling

for (int i = 0; i < values.size(); i++)
    if (values.get(i) == null) throw new IllegalArgumentException("element " + i + " is null");

Try / catch

try { /* execute */ } catch (MarshalException e) { /* null element: sanitize and retry */ }

Prevention

When it happens

Trigger: Executing a statement whose vector literal or term list contains a null element, e.g. [1, null, 3] for vector<int, 3>, or a bound parameter that resolves to null inside a MultiElements.DelayedValue.

Common situations: Bind variables left null in the driver before executing; queries built from partially-populated data structures; missing embedding values in ML pipelines.

Related errors


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