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
- Ensure the value contains exactly dimension * elementSize bytes before calling decomposeAsFloat/fromComparableBytes
- Treat null/empty as a special case in application code and skip the call or insert a null vector explicitly if allowed
- 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
- Never insert empty blobs into vector columns; use null instead if allowed
- Check producer/driver code never emits zero-length payloads
- Add size assertions in ingestion pipelines
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
- Not enough bytes to read a
- Not enough bytes to read a vector<
- Unexpected extraneous bytes after value
- Attempted to add float vector of dimension
- cannot parse ' ' as hex bytes
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)