apache/cassandra · error · MarshalException

Not enough bytes to read the end-of-component byte of compon

Error message

Not enough bytes to read the end-of-component byte of component

What it means

Each composite component must end with a single end-of-component byte (normally 0), which also determines ascending/descending order. AbstractCompositeType.validate() throws MarshalException 'Not enough bytes to read the end-of-component byte of component <i>' when the buffer is exhausted right after a component's value bytes, with no room for this terminator.

Source

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

        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;
        }
    }

    @Override
    public void checkConstraints(ByteBuffer input, ColumnConstraints constraints) throws ConstraintViolationException
    {
        // no constraints defined for the partition keys
        if (!constraints.hasRelevantConstraints())
            return;

        ValueAccessor<ByteBuffer> accessor = ByteBufferAccessor.instance;

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Append the required 0x00 end-of-component byte after every component value when building composites manually
  2. Use CompositeType.decompose()/build to produce correct framing automatically
  3. Check any slicing/copy code so it does not trim the final byte
  4. Verify totals: every component consumes comparator + 2 + len + 1 bytes
  5. Run nodetool scrub if corrupt stored data is the source

Example fix

// before
out.put(value); // component written without end-of-component byte
// after
out.put(value);
out.put((byte) 0x00);
Defensive patterns

Strategy: validation

Validate before calling

// ensure at least 1 byte remains after each component value
int off = 0, i = 0;
while (off < buf.remaining()) {
    int hdr = /* comparator size */ 1;
    int len = ((buf.get(off + hdr) & 0xff) << 8) | (buf.get(off + hdr + 1) & 0xff);
    if (buf.remaining() < off + hdr + 2 + len + 1)
        throw new IllegalArgumentException("Component " + i + " missing end-of-component byte");
    off += hdr + 2 + len + 1; ++i;
}

Try / catch

try {
    type.validate(bytes);
} catch (MarshalException e) {
    if (e.getMessage().startsWith("Not enough bytes to read the end-of-component"))
        logger.error("Composite missing 0x00 terminator — use decompose() to build values");
    else throw e;
}

Prevention

When it happens

Trigger: Validating a composite blob that ends exactly after a component's value without the trailing 0x00 end-of-component byte — e.g. manually built keys omitting the terminator or truncated payloads.

Common situations: Hand-written composite encoders forgetting the 0 terminator; byte-range slicing dropping the last byte; older/other-system formats (e.g. Thrift-era helpers) that differ in encoding; corrupted sstable values.

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