apache/cassandra · error · MarshalException

Invalid empty vector value

Error message

Invalid empty vector value

What it means

VectorType rejects empty or null vector values because a vector's size is fixed by its dimension; an empty byte buffer cannot represent dimension elements. rejectNullOrEmptyValue is invoked from decomposeAsFloat and fromComparableBytes when the incoming value is null or has zero remaining bytes.

Solutions

  1. Ensure the value contains exactly dimension * elementSize bytes before calling decomposeAsFloat/fromComparableBytes
  2. Treat null/empty as a special case in application code and skip the call or insert a null vector explicitly if allowed
  3. Fix producer code (driver, migration script) so it never emits empty vectors for non-zero dimension columns

Example fix

// before
float[] floats = vectorType.decomposeAsFloat(ByteBuffer.wrap(new byte[0]));
// after
if (value == null || value.remaining() == 0) throw new IllegalArgumentException("vector value must not be empty");
float[] floats = vectorType.decomposeAsFloat(value);
Defensive patterns

Strategy: validation

Validate before calling

if (value == null || value.remaining() == 0) throw new IllegalArgumentException("vector value must be non-empty");

Try / catch

try { float[] v = vectorType.decomposeAsFloat(buf); } catch (MarshalException e) { log.warn("empty/invalid vector: {}", e.getMessage()); v = null; }

Prevention

When it happens

Trigger: Calling decomposeAsFloat or fromComparableBytes with a null buffer or an empty (0-byte) ByteBuffer for a vector column; inserting an empty blob into a vector column path that goes through these methods.

Common situations: Application code sending an empty payload for a vector column; deserialization returning empty bytes; migration tooling producing empty values; test code constructing vectors incorrectly.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

        // 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()
    {
        List<ByteBuffer> values = Collections.nCopies(dimension, elementType.getMaskedValue());
        return serializer.pack(values, ByteBufferAccessor.instance);
    }

    public abstract class VectorSerializer extends TypeSerializer<List<T>>
    {
        public abstract <VL, VR> int compareCustom(VL left, ValueAccessor<VL> accessorL, VR right, ValueAccessor<VR> accessorR);

        public abstract <V> List<V> unpack(V buffer, ValueAccessor<V> accessor);
        public abstract <V> V pack(List<V> elements, ValueAccessor<V> accessor);

        @Override
        public String toString(List<T> value)

View on GitHub (pinned to 88fd0f6a0e)