apache/cassandra · error · MarshalException

Not enough bytes to read a map

Error message

Not enough bytes to read a map

What it means

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.

Solutions

  1. Write an empty map as a serialized map with count 0 (use the serializer's serialize(Maps.newHashMap()) rather than an empty buffer).
  2. Send an actual NULL (unset/null value) through CQL instead of an empty blob.
  3. Catch MarshalException and normalize empty input to an empty serialized map before validating.
  4. Check client driver version/usage so empty collections are encoded correctly.

Example fix

// before
ByteBuffer bad = ByteBufferUtil.EMPTY_BYTE_BUFFER; // rejected
// after
Map<ByteBuffer, ByteBuffer> empty = new LinkedHashMap<>();
ByteBuffer ok = mapSerializer.serialize(empty); // 4-byte count == 0
Defensive patterns

Strategy: validation

Validate before calling

// Java
public static ByteBuffer serializeMapOrEmpty(MapType<?,?> mapType, Map<?,?> m) {
    return (m == null || m.isEmpty())
        ? mapType.getSerializer().serialize(new LinkedHashMap<>()) // 4-byte zero count
        : mapType.getSerializer().serialize(m);
}

Type guard

boolean isNonEmptyMapBytes(ByteBuffer b) { return b != null && b.remaining() >= 4; }

Try / catch

try { mapType.validate(value); } catch (MarshalException e) { /* normalize: empty buffer -> serialize empty map, else reject */ }

Prevention

When it happens

Trigger: Calling validate (directly or via MapType.validate / column validation on insert) with an empty or zero-length ByteBuffer for a map column.

Common situations: 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.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/890952fc480cbb26. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/serializers/MapSerializer.java:97

        return buffers;
    }

    public <E> int collectionSize(Collection<E> elements)
    {
        return elements.size() >> 1;
    }

    @Override
    protected int numberOfSerializedElements(int collectionSize)
    {
        return collectionSize * 2; // keys and values
    }

    @Override
    public <T> void validate(T input, ValueAccessor<T> accessor)
    {
        if (accessor.isEmpty(input))
            throw new MarshalException("Not enough bytes to read a map");
        try
        {
            int n = readCollectionSize(input, accessor);
            int offset = sizeOfCollectionSize();
            for (int i = 0; i < n; i++)
            {
                T key = readNonNullValue(input, accessor, offset);
                offset += sizeOfValue(key, accessor);
                keys.validate(key, accessor);

                T value = readNonNullValue(input, accessor, offset);
                offset += sizeOfValue(value, accessor);
                values.validate(value, accessor);
            }
            if (!accessor.isEmptyFromOffset(input, offset))
                throw new MarshalException("Unexpected extraneous bytes after map value");
        }
        catch (BufferUnderflowException | IndexOutOfBoundsException e)

View on GitHub (pinned to 88fd0f6a0e)