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
- Inspect the client code that builds the composite value and ensure each component is serialized as comparator + 2-byte length + value + 0 end-byte
- Use the driver's/type's own serializer (CompositeType.build/buildAlias) instead of manual byte assembly
- Validate the input length before sending: each component needs at least comparator-size + 3 bytes
- If data came from a migration, re-export with correct tooling and compare byte lengths
- 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
- Never assemble composite bytes manually; use the type's decompose/build API
- Don't round-trip binary composite values through String/UTF-8
- Base64-encode composite blobs for logs/transport and decode before sending
- Validate blobs with type.validate(bytes) in tests for any migration tooling
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
- Not enough bytes to read value 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/50a23a4716b2b719.
Report an issue: GitHub.