apache/cassandra · error · MarshalException
Unexpected extraneous bytes after map value
Error message
Unexpected extraneous bytes after map value
What it means
After validating all declared key/value entries of a serialized map, MapSerializer.verify valid positions... actually MapSerializer.validate checks that no leftover bytes remain: if the buffer still has bytes after the last element, this MarshalException is thrown. It means the byte buffer contains more data than the map's declared structure consumes — trailing garbage or a value that is not a map.
Solutions
- Use the correct type/serializer — confirm the column type matches the bytes being validated.
- Trim the buffer to exactly the map's consumed bytes if extra bytes are expected by your producer.
- Catch MarshalException and reject the write/mutation as invalid input.
- If the data is stored on disk, treat as corruption and run scrub/repair.
Example fix
// before mapType.validate(listBytes); // wrong type bytes // after mapType.validate(mapBytes); // validate with the matching serializer
Defensive patterns
Strategy: validation
Validate before calling
// Java // Ensure the byte stream is fully consumed by the declared structure before validating: mapType.validate(buffer); // throws 'Unexpected extraneous bytes after map value' when trailing bytes exist
Try / catch
try { mapType.validate(bytes); } catch (MarshalException e) { throw new InvalidRequestException("Value is not a valid map: " + e.getMessage()); } Prevention
- Match the serializer to the column type; never validate list/set bytes with the map type.
- Producers must emit exactly count + entries — no appended metadata.
- Round-trip test: serialize then validate every custom write path.
When it happens
Trigger: Validating a buffer whose declared element count times (4+len key) + (4+len value) is less than the buffer size — e.g. concatenating values, wrong serializer used (list bytes validated as a map with keys fitting), or corrupted cell with appended bytes.
Common situations: Passing frozen<list> bytes to a map type, blob literals that contain extra bytes, cells written by buggy code that appends metadata after the map.
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
- Not enough bytes to read a map
- Expected 1 byte for a tinyint
- Expected 1 or 0 byte value
- Expected 2 bytes for a smallint
- Invalid byte for ascii: + Byte.toString(b)
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/91dae4184587e496.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/serializers/MapSerializer.java:113
{
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)
{
throw new MarshalException("Not enough bytes to read a map");
}
}
@Override
public <I> Map<K, V> deserialize(I input, ValueAccessor<I> accessor)
{
try
{
int n = readCollectionSize(input, accessor);
int offset = sizeOfCollectionSize();
if (n < 0)
throw new MarshalException("The data cannot be deserialized as a map");
View on GitHub (pinned to 88fd0f6a0e)