apache/cassandra · error · MarshalException

Not enough bytes to read a list

Error message

Not enough bytes to read a list

What it means

ListSerializer.validate() throws this when the input buffer is completely empty, because a serialized list must contain at least the collection-size count. An empty buffer cannot even be read as a count, so validation fails immediately. Note that an empty list is represented by a size of 0 with bytes present — not by zero bytes.

Source

Thrown at src/java/org/apache/cassandra/serializers/ListSerializer.java:73

    private ListSerializer(TypeSerializer<T> elements)
    {
        this.elements = elements;
    }

    @Override
    protected List<ByteBuffer> serializeValues(List<T> values)
    {
        List<ByteBuffer> output = new ArrayList<>(values.size());
        for (T value: values)
            output.add(elements.serialize(value));
        return output;
    }

    @Override
    public <V> void validate(V input, ValueAccessor<V> accessor)
    {
        if (accessor.isEmpty(input))
            throw new MarshalException("Not enough bytes to read a list");
        try
        {
            int n = readCollectionSize(input, accessor);
            int offset = sizeOfCollectionSize();
            for (int i = 0; i < n; i++)
            {
                V value = readNonNullValue(input, accessor, offset);
                offset += sizeOfValue(value, accessor);
                elements.validate(value, accessor);
            }

            if (!accessor.isEmptyFromOffset(input, offset))
                throw new MarshalException("Unexpected extraneous bytes after list value");
        }
        catch (BufferUnderflowException | IndexOutOfBoundsException e)
        {
            throw new MarshalException("Not enough bytes to read a list");
        }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Serialize even empty lists with their element count (a 4-byte zero) using ListSerializer.serialize / the driver's list codec, not an empty buffer.
  2. Bind null (unset) instead of an empty buffer when the intent is 'no value'.
  3. If the column can legitimately hold no list, consider allowing null and skipping the write.
  4. Check for code paths that coerce null to ByteBufferUtil.EMPTY_BYTE_BUFFER before binding.

Example fix

// before
ByteBuffer bytes = ByteBufferUtil.EMPTY_BYTE_BUFFER; // empty blob
// after
ByteBuffer bytes = ListSerializer.instance.serialize(Collections.emptyList(), ByteBufferUtil.NONE); // encodes count=0
Defensive patterns

Strategy: validation

Validate before calling

if (listBytes == null || listBytes.remaining() == 0) { listBytes = ListSerializer.instance.serialize(Collections.emptyList(), Int32Type.instance, ByteBufferUtil.NONE); }

Type guard

boolean isNonEmptyListBlob(java.nio.ByteBuffer b) { return b != null && b.remaining() >= 4; }

Try / catch

try { listType.validate(buf, accessor); } catch (org.apache.cassandra.exceptions.MarshalException e) { log.warn("empty/malformed list blob, treating as null"); return null; }

Prevention

When it happens

Trigger: Calling ListSerializer.validate(input, accessor) (directly or via ListType column validation) with an empty (0-byte) buffer; e.g. writing ByteBufferUtil.EMPTY_BYTE_BUFFER or null-serialized bytes into a list column.

Common situations: Application serializes an empty Java List as an empty buffer instead of a zero-count collection; a driver binds null differently across versions (pre-3.0 empty bytes vs null); ETL tools writing empty blobs into list columns; upgrading from older Cassandra versions where empty collections were allowed/represented differently.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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