apache/cassandra · error · MarshalException

Not enough bytes to read value size of component

Error message

Not enough bytes to read value size of component 

What it means

AbstractCompositeType.validate() walks the serialized composite value: for each component it reads a 2-byte unsigned-short size, then that many value bytes, then an end-of-component byte. If fewer than 2 bytes remain where the component's value size should be, MarshalException 'Not enough bytes to read value size of component <i>' is thrown, indicating a truncated or malformed composite blob.

Source

Thrown at src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java:313

    {
        validate(bb, ByteBufferAccessor.instance);
    }

    @Override
    public <V> void validate(V input, ValueAccessor<V> accessor)
    {
        boolean isStatic = readIsStatic(input, accessor);
        int offset = startingOffset(isStatic);

        int i = 0;
        V previous = null;
        while (!accessor.isEmptyFromOffset(input, offset))
        {
            AbstractType<?> comparator = validateComparator(i, input, accessor, offset);
            offset += getComparatorSize(i, input, accessor, offset);

            if (accessor.sizeFromOffset(input, offset) < 2)
                throw new MarshalException("Not enough bytes to read value size of component " + i);
            int length = accessor.getUnsignedShort(input, offset);
            offset += 2;

            if (accessor.sizeFromOffset(input, offset) < length)
                throw new MarshalException("Not enough bytes to read value of component " + i);
            V value = accessor.slice(input, offset, length);
            offset += length;

            comparator.validateCollectionMember(value, previous, accessor);

            if (accessor.isEmptyFromOffset(input, offset))
                throw new MarshalException("Not enough bytes to read the end-of-component byte of component" + i);
            byte b = accessor.getByte(input, offset++);
            if (b != 0 && !accessor.isEmptyFromOffset(input, offset))
                throw new MarshalException("Invalid bytes remaining after an end-of-component at component" + i);

            previous = value;
            ++i;

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Inspect the client code that builds the composite value and ensure each component is serialized as comparator + 2-byte length + value + 0 end-byte
  2. Use the driver's/type's own serializer (CompositeType.build/buildAlias) instead of manual byte assembly
  3. Validate the input length before sending: each component needs at least comparator-size + 3 bytes
  4. If data came from a migration, re-export with correct tooling and compare byte lengths
  5. If from a corrupted sstable, run nodetool scrub on the table

Example fix

// before: manual truncating copy
byte[] out = Arrays.copyOfRange(src, 0, src.length - 1); // drops end byte
// after
ByteBuffer out = CompositeType.getInstance(Arrays.asList(UTF8Type.instance, Int32Type.instance))
                              .decompose(Arrays.asList("a", 1));
Defensive patterns

Strategy: validation

Validate before calling

// client-side pre-check for a composite blob
int off = 0, i = 0;
while (off < buf.remaining()) {
    int compHeader = /* comparator size for this composite type, min 1 */ 1;
    if (buf.remaining() - off < compHeader + 2)
        throw new IllegalArgumentException("Truncated composite at component " + i);
    int len = ((buf.get(off + compHeader) & 0xff) << 8) | (buf.get(off + compHeader + 1) & 0xff);
    if (buf.remaining() - off - compHeader - 2 < len + 1)
        throw new IllegalArgumentException("Component " + i + " overruns buffer");
    off += compHeader + 2 + len + 1; ++i;
}

Try / catch

try {
    type.validate(bytes);
} catch (MarshalException e) {
    if (e.getMessage().startsWith("Not enough bytes to read value size"))
        logger.error("Truncated composite blob — rebuild with CompositeType.decompose");
    else throw e;
}

Prevention

When it happens

Trigger: Validating (or deserializing via CQL/client insert) a composite-typed value whose bytes end immediately after a comparator header, before the 2-byte length field of component i can be read.

Common situations: Client code hand-constructing composite keys/blobs with truncated payloads; corrupted values from a bad driver or migration tool; binary blobs pasted between systems with wrong encoding; reading partial rows from corrupted sstables.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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