{"record":{"id":"0fefe7914482c745","repo":"apache/cassandra","slug":"unexpected-extraneous-bytes-after-list-value","errorCode":null,"errorMessage":"Unexpected extraneous bytes after list value","messagePattern":"Unexpected extraneous bytes after list value","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/serializers/ListSerializer.java","lineNumber":86,"sourceCode":"\n    @Override\n    public <V> void validate(V input, ValueAccessor<V> accessor)\n    {\n        if (accessor.isEmpty(input))\n            throw new MarshalException(\"Not enough bytes to read a list\");\n        try\n        {\n            int n = readCollectionSize(input, accessor);\n            int offset = sizeOfCollectionSize();\n            for (int i = 0; i < n; i++)\n            {\n                V value = readNonNullValue(input, accessor, offset);\n                offset += sizeOfValue(value, accessor);\n                elements.validate(value, accessor);\n            }\n\n            if (!accessor.isEmptyFromOffset(input, offset))\n                throw new MarshalException(\"Unexpected extraneous bytes after list value\");\n        }\n        catch (BufferUnderflowException | IndexOutOfBoundsException e)\n        {\n            throw new MarshalException(\"Not enough bytes to read a list\");\n        }\n    }\n\n    @Override\n    public <V> List<T> deserialize(V input, ValueAccessor<V> accessor)\n    {\n        try\n        {\n            int n = readCollectionSize(input, accessor);\n            int offset = sizeOfCollectionSize();\n\n            if (n < 0)\n                throw new MarshalException(\"The data cannot be deserialized as a list\");\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/serializers/ListSerializer.java#L68-L104","documentation":"After reading the declared number of list elements, ListSerializer.validate() checks that no bytes remain between the current offset and the end of the buffer. Leftover trailing bytes mean the buffer is longer than the encoded list it claims to contain, so the data is corrupt or mis-framed. This catches buffers that concatenate a list with unrelated extra data.","triggerScenarios":"Calling ListSerializer.validate(input, accessor) where n elements read successfully but accessor.isEmptyFromOffset(input, offset) is false — i.e. extra bytes remain after the last element.","commonSituations":"Manual byte-concatenation of a list with a delimiter or padding; sending a frozen<list> blob that embeds extra fields; truncated/corrupt SSTable or hint data being re-validated; off-by-one errors in hand-rolled collection serialization.","solutions":["Regenerate the serialized list with the official ListSerializer instead of hand-built buffers.","Inspect the source of the buffer (ETL job, migration tool) for extra padding or appended fields and strip them.","Check for double-wrapping: a ByteBuffer serialized inside another collection framing.","If data at rest is corrupt, run a repair/scrub to rewrite the affected rows."],"exampleFix":"// before\nByteBuffer bad = ByteBuffer.allocate(4 + 4).putInt(0).putInt(42); // count + trailing int\n// after\nList<Integer> l = Collections.singletonList(42);\nByteBuffer good = ListSerializer.instance.serialize(l, Int32Type.instance, ByteBufferUtil.NONE); // use proper serializer","handlingStrategy":"try-catch","validationCode":"// pre-validate framing: expected bytes = 4 + sum(element sizes); if (blob.remaining() != expected) reject before validate()","typeGuard":null,"tryCatchPattern":"try { listSerializer.validate(blob, ByteBufferUtil.NONE); } catch (org.apache.cassandra.exceptions.MarshalException e) { log.error(\"list blob misframed: {}\", e.getMessage()); blob = reSerializeFromSource(); }","preventionTips":["Never hand-build collection buffers; use ListSerializer.serialize or driver codecs","Strip padding/delimiters added by ETL pipelines before storing blobs","Run scrub/repair if at-rest rows repeatedly fail validation"],"tags":["cassandra","serialization","collections","list"],"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"}