{"record":{"id":"53f7bff2f55b42be","repo":"apache/cassandra","slug":"not-enough-bytes-to-read-size-of-dth-component","errorCode":null,"errorMessage":"Not enough bytes to read size of %dth component","messagePattern":"Not enough bytes to read size of (.+?)th component","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/CQL3Type.java","lineNumber":494,"sourceCode":"        }\n\n        public String toCQLLiteral(ByteBuffer buffer)\n        {\n            if (buffer == null)\n                return \"null\";\n\n            StringBuilder target = new StringBuilder();\n            buffer = buffer.duplicate();\n            target.append('(');\n            boolean first = true;\n            for (int i = 0; i < type.size(); i++)\n            {\n                // we allow the input to have less fields than declared so as to support field addition.\n                if (!buffer.hasRemaining())\n                    break;\n\n                if (buffer.remaining() < 4)\n                    throw new MarshalException(String.format(\"Not enough bytes to read size of %dth component\", i));\n\n                int size = buffer.getInt();\n\n                if (first)\n                    first = false;\n                else\n                    target.append(\", \");\n\n                // size < 0 means null value\n                if (size < 0)\n                {\n                    target.append(\"null\");\n                    continue;\n                }\n\n                if (buffer.remaining() < size)\n                    throw new MarshalException(String.format(\"Not enough bytes to read %dth component\", i));\n","sourceCodeStart":476,"sourceCodeEnd":512,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/CQL3Type.java#L476-L512","documentation":"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.","triggerScenarios":"Passing a truncated ByteBuffer to toCQLLiteral for a TupleType; manually assembling tuple bytes with missing components; slicing a serialized tuple at a non-boundary.","commonSituations":"Bugs in custom code serializing tuples into blobs; partial reads from storage; mixing up frozen tuple encodings across versions.","solutions":["Confirm the buffer holds a fully serialized tuple (all declared components present, unless intentionally fewer for field addition)","Rebuild the value with TupleType.serializer / newValue() APIs","Validate buffer length against the tuple's component count before rendering"],"exampleFix":"// before\nString lit = tupleType.asCQL3Type().toCQLLiteral(buffer.slice(0, 2)); // cut mid-header\n// after\nString lit = tupleType.asCQL3Type().toCQLLiteral(fullSerializedTuple.duplicate());","handlingStrategy":"try-catch","validationCode":"if (buffer == null || buffer.remaining() < 4) throw new MarshalException(\"Buffer too small for tuple component\");","typeGuard":null,"tryCatchPattern":"try { String lit = tupleType.asCQL3Type().toCQLLiteral(buffer); } catch (MarshalException e) { log.error(\"Corrupt tuple value\", e); }","preventionTips":["Build tuple values with TupleType newValue(...), not manual byte composition","Verify component count matches the tuple definition","Validate buffer completeness before literal conversion"],"tags":["cassandra","cql","serialization","tuple","bytebuffer"],"backgroundTag":"unexpected-response-shape","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}