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
- Append the required 0x00 end-of-component byte after every component value when building composites manually
- Use CompositeType.decompose()/build to produce correct framing automatically
- Check any slicing/copy code so it does not trim the final byte
- Verify totals: every component consumes comparator + 2 + len + 1 bytes
- 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
- Always write the 0x00 end-of-component byte after each component when encoding manually
- Prefer CompositeType.decompose over bespoke encoders
- Beware byte-slicing that trims the final terminator byte
- Scrub tables (nodetool scrub) when stored values are suspect
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
- Not enough bytes to read value size of component
- Not enough bytes to read value of component
- Invalid bytes remaining after an end-of-component at compone
- Invalid byte for ascii: + Byte.toString(b)
- Expected 1 or 0 byte value (%d)
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/da91b43fc1b01d3f.
Report an issue: GitHub.