apache/cassandra · error · MarshalException

Not enough bytes to read size of %dth component

Error message

Not enough bytes to read size of %dth component

What it means

Analogous to the UDT case: when converting a serialized tuple value to a CQL literal, each component's 4-byte size prefix must be readable. If fewer than 4 bytes remain for the next component, MarshalException is thrown ('%dth component') because the serialized tuple is truncated.

Source

Thrown at src/java/org/apache/cassandra/cql3/CQL3Type.java:494

        }

        public String toCQLLiteral(ByteBuffer buffer)
        {
            if (buffer == null)
                return "null";

            StringBuilder target = new StringBuilder();
            buffer = buffer.duplicate();
            target.append('(');
            boolean first = true;
            for (int i = 0; i < type.size(); i++)
            {
                // we allow the input to have less fields than declared so as to support field addition.
                if (!buffer.hasRemaining())
                    break;

                if (buffer.remaining() < 4)
                    throw new MarshalException(String.format("Not enough bytes to read size of %dth component", i));

                int size = buffer.getInt();

                if (first)
                    first = false;
                else
                    target.append(", ");

                // size < 0 means null value
                if (size < 0)
                {
                    target.append("null");
                    continue;
                }

                if (buffer.remaining() < size)
                    throw new MarshalException(String.format("Not enough bytes to read %dth component", i));

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Confirm the buffer holds a fully serialized tuple (all declared components present, unless intentionally fewer for field addition)
  2. Rebuild the value with TupleType.serializer / newValue() APIs
  3. Validate buffer length against the tuple's component count before rendering

Example fix

// before
String lit = tupleType.asCQL3Type().toCQLLiteral(buffer.slice(0, 2)); // cut mid-header
// after
String lit = tupleType.asCQL3Type().toCQLLiteral(fullSerializedTuple.duplicate());
Defensive patterns

Strategy: try-catch

Validate before calling

if (buffer == null || buffer.remaining() < 4) throw new MarshalException("Buffer too small for tuple component");

Try / catch

try { String lit = tupleType.asCQL3Type().toCQLLiteral(buffer); } catch (MarshalException e) { log.error("Corrupt tuple value", e); }

Prevention

When it happens

Trigger: Passing a truncated ByteBuffer to toCQLLiteral for a TupleType; manually assembling tuple bytes with missing components; slicing a serialized tuple at a non-boundary.

Common situations: Bugs in custom code serializing tuples into blobs; partial reads from storage; mixing up frozen tuple encodings across versions.

Related errors


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