apache/cassandra · error · MarshalException

Not enough bytes to read a set

Error message

Not enough bytes to read a set

What it means

SetSerializer.validate rejects an empty (zero-byte) value because a valid serialized set must contain at least the collection-size prefix. Cassandra historically serializes empty collections as null; a zero-length buffer is therefore treated as malformed rather than as an empty set. This guard runs during validation of values being written or bound.

Solutions

  1. Pass null instead of an empty buffer to unset/delete the set, or pass a properly encoded set of the elements you want.
  2. If the intent is to store an empty set, encode it with SetSerializer.serialize(Collections.emptySet()) (4-byte zero count) rather than a zero-length buffer.
  3. In test code, use the serializer's own serialize method to build valid inputs.

Example fix

// before
boundStatement.setBytes("tags", ByteBuffer.allocate(0));
// after
boundStatement.setToNull("tags"); // or
boundStatement.setSet("tags", Collections.emptySet(), String.class);
Defensive patterns

Strategy: validation

Validate before calling

// Java
if (buf == null || buf.remaining() == 0) {
    // treat as unset; bind null instead
} else {
    setSerializer.validate(buf.duplicate(), ByteBufferAccessor.instance);
}

Try / catch

try {
    setSerializer.validate(buf, ByteBufferAccessor.instance);
} catch (MarshalException e) {
    throw new IllegalArgumentException("Invalid set value: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Binding a zero-length ByteBuffer to a set column (e.g. ByteBufferUtil.EMPTY_BYTE_BUFFER) via execute/bound statements, or validating an empty buffer in a custom type test such as setSerDerTest.

Common situations: Client drivers or app code constructing an empty set value as an empty buffer instead of null; migrations that write empty collections; custom serialization tests feeding empty input.

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/e662b75b8379fcff. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/serializers/SetSerializer.java:74

        this.elements = elements;
        this.comparators = comparators;
    }

    @Override
    public List<ByteBuffer> serializeValues(Set<T> values)
    {
        List<ByteBuffer> buffers = new ArrayList<>(values.size());
        for (T value : values)
            buffers.add(elements.serialize(value));
        buffers.sort(comparators.buffer);
        return buffers;
    }

    @Override
    public <V> void validate(V input, ValueAccessor<V> accessor)
    {
        if (accessor.isEmpty(input))
            throw new MarshalException("Not enough bytes to read a set");
        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 set value");
        }
        catch (BufferUnderflowException | IndexOutOfBoundsException e)
        {
            throw new MarshalException("Not enough bytes to read a set");
        }
    }

View on GitHub (pinned to 88fd0f6a0e)