{"record":{"id":"f1a172a3c0a2785e","repo":"apache/cassandra","slug":"not-enough-bytes-to-read-a-getcollectionname","errorCode":null,"errorMessage":"Not enough bytes to read a + getCollectionName()","messagePattern":"Not enough bytes to read a \\+ getCollectionName\\(\\)","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/serializers/CollectionSerializer.java","lineNumber":104,"sourceCode":"            List<V> values = new ArrayList<>(Math.min(elements, 256));\n            int offset = sizeOfCollectionSize();\n\n            for (int i = 0; i < elements; i++)\n            {\n                V value = readValue(input, accessor, offset);\n                offset += sizeOfValue(value, accessor);\n\n                values.add(value);\n            }\n\n            if (!accessor.isEmptyFromOffset(input, offset))\n                throw new MarshalException(\"Unexpected extraneous bytes after \" + getCollectionName() + \" value\");\n\n            return values;\n        }\n        catch (BufferUnderflowException | IndexOutOfBoundsException e)\n        {\n            throw new MarshalException(\"Not enough bytes to read a \" + getCollectionName());\n        }\n    }\n\n    /**\n     * Return the collection name for error messages.\n     * @return the collection name for error messages.\n     */\n    private String getCollectionName()\n    {\n        return toLowerCaseLocalized(getType().getSimpleName());\n    }\n\n    /**\n     * Returns the size of the collections from the number of serialized elements.\n     *\n     * @param <E> the value type, ByteBuffer or byte[]\n     * @param elements the serialized elements\n     * @return the size of the collections from the number of serialized elements.","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/serializers/CollectionSerializer.java#L86-L122","documentation":"unpack() reads the element count then iterates that many elements from the buffer. If the buffer ends before all declared elements can be read, a BufferUnderflowException/IndexOutOfBoundsException is caught and rethrown as this MarshalException, meaning the serialized collection is truncated.","triggerScenarios":"deserialize/validate called with a buffer shorter than count * element sizes — truncated network frames, partially written SSTable bytes, or a count prefix that overstates the number of elements.","commonSituations":"Slicing ByteBuffers incorrectly (wrong position/limit) before deserializing; corrupted data files; reading a collection value with a stale cell size after schema/version mismatch.","solutions":["Check that the buffer slice passed to deserialize contains the full value (position/limit correct)","Verify source data integrity (repair/scrub if from disk)","Re-serialize the collection from the original object model","Confirm count prefix matches actual number of encoded elements in custom serialization code"],"exampleFix":"// before\nByteBuffer truncated = full.duplicate(); truncated.limit(full.position() + 3); // cut mid-value\n// after\nByteBuffer ok = full.duplicate(); ok.limit(full.position() + sizeOfSerializedCollection);","handlingStrategy":"validation","validationCode":"public static void checkNotTruncated(ByteBuffer buf, int minBytes) {\n    if (buf == null || buf.remaining() < minBytes)\n        throw new MarshalException(\"expected at least \" + minBytes + \" bytes, got \" + (buf == null ? 0 : buf.remaining()));\n}","typeGuard":"public static boolean hasEnoughBytes(ByteBuffer buf, int min) {\n    return buf != null && buf.remaining() >= min;\n}","tryCatchPattern":"try {\n    Object value = serializer.deserialize(buffer);\n} catch (MarshalException e) {\n    if (e.getMessage().startsWith(\"Not enough bytes\")) {\n        logger.error(\"Truncated collection value\");\n    }\n}","preventionTips":["Slice buffers with correct position and limit before deserializing","Keep count prefix consistent with actual element count in custom code","Use checksums/repair to catch truncated data at rest"],"tags":["serialization","cassandra","bytebuffer","truncated-data"],"backgroundTag":"invalid-argument-format","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}