apache/cassandra · error · MarshalException
Not enough bytes to read value of component
Error message
Not enough bytes to read value of component
What it means
During AbstractCompositeType.validate(), after reading a component's 2-byte size header the validator checks that `length` bytes are actually available. If fewer remain, MarshalException 'Not enough bytes to read value of component <i>' is thrown — the declared component length exceeds the remaining bytes, so the composite blob is truncated or the length header is wrong.
Source
Thrown at src/java/org/apache/cassandra/db/marshal/AbstractCompositeType.java:318
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;
}
}
@Override
public void checkConstraints(ByteBuffer input, ColumnConstraints constraints) throws ConstraintViolationExceptionView on GitHub (pinned to 88fd0f6a0e)
Solutions
- Fix the serializer that writes the component length so it writes the exact value byte count as an unsigned short
- Avoid round-tripping composite bytes through text encodings (Base64 or hex for transport instead)
- Use the type's decompose()/build API rather than manual ByteBuffer assembly
- Compare expected vs actual total byte length before submit: comparator sizes + sum(lengths+3)
- Scrub/rebuild the table if stored sstable data is corrupt
Example fix
// before bb.putShort((short) value.length); bb.put(value, 0, value.length - 1); // wrong: one byte short // after bb.putShort((short) value.length); bb.put(value);
Defensive patterns
Strategy: validation
Validate before calling
// check every component's declared length fits before calling the API
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)
throw new IllegalArgumentException("Component " + i + " length " + len + " exceeds remaining bytes");
off += hdr + 2 + len + 1; ++i;
} Try / catch
try {
type.validate(bytes);
} catch (MarshalException e) {
if (e.getMessage().startsWith("Not enough bytes to read value of component"))
logger.error("Composite length header corrupt — reserialize with decompose()");
else throw e;
} Prevention
- Write lengths with exactly the value byte count using ByteBuffer.putShort before put(value)
- Skip length-field math entirely by using CompositeType.build/decompose
- Hex-dump suspicious blobs and verify framing: header + 2-byte len + value + 0 terminator
- Re-serialize values after any tooling that resizes or transforms them
When it happens
Trigger: Validating a serialized composite where a component advertises (via its unsigned-short length) more bytes than remain in the buffer — typical of hand-built composites with incorrect length fields or truncated byte arrays.
Common situations: Off-by-one or wrong-endian length writing in custom code building composite keys; truncation when copying values through string/UTF-8 conversions; import/export tools mangling binary values; corrupted stored 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 the end-of-component byte of compon
- 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/b54101ef95149027.
Report an issue: GitHub.