{"record":{"id":"890952fc480cbb26","repo":"apache/cassandra","slug":"not-enough-bytes-to-read-a-map","errorCode":null,"errorMessage":"Not enough bytes to read a map","messagePattern":"Not enough bytes to read a map","errorType":"validation","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/serializers/MapSerializer.java","lineNumber":97,"sourceCode":"        return buffers;\n    }\n\n    public <E> int collectionSize(Collection<E> elements)\n    {\n        return elements.size() >> 1;\n    }\n\n    @Override\n    protected int numberOfSerializedElements(int collectionSize)\n    {\n        return collectionSize * 2; // keys and values\n    }\n\n    @Override\n    public <T> void validate(T input, ValueAccessor<T> accessor)\n    {\n        if (accessor.isEmpty(input))\n            throw new MarshalException(\"Not enough bytes to read a map\");\n        try\n        {\n            int n = readCollectionSize(input, accessor);\n            int offset = sizeOfCollectionSize();\n            for (int i = 0; i < n; i++)\n            {\n                T key = readNonNullValue(input, accessor, offset);\n                offset += sizeOfValue(key, accessor);\n                keys.validate(key, accessor);\n\n                T value = readNonNullValue(input, accessor, offset);\n                offset += sizeOfValue(value, accessor);\n                values.validate(value, accessor);\n            }\n            if (!accessor.isEmptyFromOffset(input, offset))\n                throw new MarshalException(\"Unexpected extraneous bytes after map value\");\n        }\n        catch (BufferUnderflowException | IndexOutOfBoundsException e)","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/serializers/MapSerializer.java#L79-L115","documentation":"MapSerializer.validate first rejects an empty buffer with \"Not enough bytes to read a map\" because a serialized map must start with at least a 4-byte element count. This is thrown before any element parsing when input is empty. An empty map must still be serialized with a count of 0, not as zero bytes.","triggerScenarios":"Calling validate (directly or via MapType.validate / column validation on insert) with an empty or zero-length ByteBuffer for a map column.","commonSituations":"Client code writing an empty map as an empty buffer instead of a 0-count serialized map; blob literals of length 0 bound to map columns; uninitialized ByteBuffers in custom code.","solutions":["Write an empty map as a serialized map with count 0 (use the serializer's serialize(Maps.newHashMap()) rather than an empty buffer).","Send an actual NULL (unset/null value) through CQL instead of an empty blob.","Catch MarshalException and normalize empty input to an empty serialized map before validating.","Check client driver version/usage so empty collections are encoded correctly."],"exampleFix":"// before\nByteBuffer bad = ByteBufferUtil.EMPTY_BYTE_BUFFER; // rejected\n// after\nMap<ByteBuffer, ByteBuffer> empty = new LinkedHashMap<>();\nByteBuffer ok = mapSerializer.serialize(empty); // 4-byte count == 0","handlingStrategy":"validation","validationCode":"// Java\npublic static ByteBuffer serializeMapOrEmpty(MapType<?,?> mapType, Map<?,?> m) {\n    return (m == null || m.isEmpty())\n        ? mapType.getSerializer().serialize(new LinkedHashMap<>()) // 4-byte zero count\n        : mapType.getSerializer().serialize(m);\n}","typeGuard":"boolean isNonEmptyMapBytes(ByteBuffer b) { return b != null && b.remaining() >= 4; }","tryCatchPattern":"try { mapType.validate(value); } catch (MarshalException e) { /* normalize: empty buffer -> serialize empty map, else reject */ }","preventionTips":["Never encode empty collections as zero-length buffers; use count=0 serialization or CQL NULL.","Always build collection values through the type's serializer.","Add unit tests that validate every collection value your code produces."],"tags":["serialization","collections","validation"],"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"}