{"record":{"id":"a87f74dfe9bd42ca","repo":"apache/cassandra","slug":"not-enough-bytes-to-read-a-s","errorCode":null,"errorMessage":"Not enough bytes to read a %s","messagePattern":"Not enough bytes to read a (.+?)","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/marshal/CollectionType.java","lineNumber":148,"sourceCode":"        {\n            return ByteBufferUtil.hexToBytes(source);\n        }\n        catch (NumberFormatException e)\n        {\n            throw new MarshalException(String.format(\"cannot parse '%s' as hex bytes\", source), e);\n        }\n    }\n\n    public boolean isCollection()\n    {\n        return true;\n    }\n\n    @Override\n    public <V> void validate(V value, ValueAccessor<V> accessor) throws MarshalException\n    {\n        if (accessor.isEmpty(value))\n            throw new MarshalException(\"Not enough bytes to read a \" + toLowerCaseLocalized(kind.name()));\n        super.validate(value, accessor);\n    }\n\n    @Override\n    public <V> void validateCellValue(V cellValue, ValueAccessor<V> accessor) throws MarshalException\n    {\n        if (isMultiCell())\n            valueComparator().validateCellValue(cellValue, accessor);\n        else\n            super.validateCellValue(cellValue, accessor);\n    }\n\n    /**\n     * Checks if this collection is Map.\n     * @return <code>true</code> if this collection is a Map, <code>false</code> otherwise.\n     */\n    public boolean isMap()\n    {","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/marshal/CollectionType.java#L130-L166","documentation":"CollectionType.validate() requires at least some bytes to represent a collection value; an empty (zero-length) value cannot encode any collection (its element count cannot be read). Cassandra throws this MarshalException when a collection column is validated against an empty byte buffer, since empty collections must be represented as null, not as empty bytes.","triggerScenarios":"Calling validate()/validate() paths (e.g. via UserType or internal validation on writes) with an empty ByteBuffer for a list/set/map column; constructing a collection value with accessor.isEmpty(value)==true.","commonSituations":"Application drivers or hand-rolled serialization writing a 0-length buffer instead of null for an empty collection; schema/data produced by older versions or external tools that encode empty collections differently; thrift-era leftovers.","solutions":["Send null instead of an empty byte buffer for an empty collection value","Ensure the driver serializes collections with their element-count prefix (never 0 bytes total)","Check for custom code or tools writing raw cells that bypass collection serialization","If migrating data, rewrite legacy empty-collection cells as tombstones/null"],"exampleFix":"// before\nByteBuffer value = ByteBuffer.allocate(0);\n// after\nByteBuffer value = null; // empty collections are represented as null","handlingStrategy":"validation","validationCode":"if (value == null || value.remaining() == 0) throw new IllegalArgumentException(\"collection value must be null or non-empty\");","typeGuard":"boolean isValidCollection(ByteBuffer v) { return v == null || v.remaining() > 0; }","tryCatchPattern":null,"preventionTips":["Represent empty collections as null, never as a 0-length buffer","Rely on the driver's collection codecs instead of hand-rolling serialization","Unit-test collection serialization against CollectionType.validate"],"tags":["serialization","marshal","collection"],"backgroundTag":"schema-validation-failed","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"}