{"record":{"id":"ab73c24a57a8033b","repo":"apache/cassandra","slug":"not-enough-bytes-to-deserialize-collection","errorCode":null,"errorMessage":"Not enough bytes to deserialize collection","messagePattern":"Not enough bytes to deserialize collection","errorType":"exception","errorClass":"InvalidTypeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/functions/types/TypeCodec.java","lineNumber":2161,"sourceCode":"        @Override\n        public C deserialize(ByteBuffer bytes, ProtocolVersion protocolVersion)\n        {\n            if (bytes == null || bytes.remaining() == 0) return newInstance(0);\n            try\n            {\n                ByteBuffer input = bytes.duplicate();\n                int size = CodecUtils.readSize(input, protocolVersion);\n                C coll = newInstance(size);\n                for (int i = 0; i < size; i++)\n                {\n                    ByteBuffer databb = CodecUtils.readValue(input, protocolVersion);\n                    coll.add(eltCodec.deserialize(databb, protocolVersion));\n                }\n                return coll;\n            }\n            catch (BufferUnderflowException e)\n            {\n                throw new InvalidTypeException(\"Not enough bytes to deserialize collection\", e);\n            }\n        }\n\n        @Override\n        public String format(C value)\n        {\n            if (value == null) return \"NULL\";\n            StringBuilder sb = new StringBuilder();\n            sb.append(getOpeningChar());\n            int i = 0;\n            for (E v : value)\n            {\n                if (i++ != 0) sb.append(',');\n                sb.append(eltCodec.format(v));\n            }\n            sb.append(getClosingChar());\n            return sb.toString();\n        }","sourceCodeStart":2143,"sourceCodeEnd":2179,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/functions/types/TypeCodec.java#L2143-L2179","documentation":"Thrown by TypeCodec's collection codecs when a received buffer contains fewer bytes than the declared collection size requires, i.e. the payload is truncated or corrupt. The codec catches BufferUnderflowException while deserializing elements and rethrows it as InvalidTypeException. It indicates the serialized bytes on the wire do not conform to the collection wire format (size count then element payloads).","triggerScenarios":"deserialize() on a ByteBuffer that was truncated, sliced incorrectly, produced by a different/incompatible protocol version, or a corrupted UDT/collection value read from storage or a custom payload.","commonSituations":"Mixing driver protocol versions or codecs across services; manually slicing a row's buffer with wrong offsets; reading a value written by a buggy custom codec; damaged values from SSTable tooling or third-party ETL writing malformed collection bytes.","solutions":["Inspect and regenerate the source of the byte buffer — ensure it was produced by the same protocol version (pass the correct ProtocolVersion to deserialize)","Verify no incorrect slicing (Buffer slice/position/limit) happened before calling deserialize","Check that any custom codecs or external writers produce the canonical collection wire format (4-byte count then serialized elements)","If it comes from storage, validate the data with sstable tools and rewrite the corrupted partition"],"exampleFix":"// before\nByteBuffer bad = row.getBytesUnsafe(\"tags\").slice(0, 3); // truncated\nList<String> tags = listCodec.deserialize(bad, ProtocolVersion.V4);\n// after\nByteBuffer full = row.getBytesUnsafe(\"tags\");\nList<String> tags = listCodec.deserialize(full, protocolVersion);","handlingStrategy":"validation","validationCode":"// before deserialize\nByteBuffer buf = row.getBytesUnsafe(\"col\");\nif (buf == null || buf.remaining() < 4)\n    throw new IllegalStateException(\"Collection buffer too small to hold element count\");","typeGuard":"static boolean looksLikeCollectionBytes(ByteBuffer b) {\n    if (b == null || b.remaining() < 4) return false;\n    int n = b.getInt(b.position());\n    return n >= 0 && n <= b.remaining();\n}","tryCatchPattern":"try {\n    return codec.deserialize(buffer, protocolVersion);\n} catch (InvalidTypeException e) {\n    LOG.warn(\"Malformed/truncated collection bytes: {}\", e.getMessage());\n    return Collections.emptyList(); // or rethrow as data-corruption\n}","preventionTips":["Never slice collection buffers without keeping the full remaining() payload","Pass the exact ProtocolVersion the bytes were encoded with","Audit any custom codecs or ETL writers against the canonical collection wire format"],"tags":["cassandra","java-driver","deserialization","corrupt-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-14T16:17:12.679Z"}