apache/cassandra · error · MarshalException

Not enough bytes to read a + getCollectionName()

Error message

Not enough bytes to read a + getCollectionName()

What it means

unpack() reads the element count then iterates that many elements from the buffer. If the buffer ends before all declared elements can be read, a BufferUnderflowException/IndexOutOfBoundsException is caught and rethrown as this MarshalException, meaning the serialized collection is truncated.

Solutions

  1. Check that the buffer slice passed to deserialize contains the full value (position/limit correct)
  2. Verify source data integrity (repair/scrub if from disk)
  3. Re-serialize the collection from the original object model
  4. Confirm count prefix matches actual number of encoded elements in custom serialization code

Example fix

// before
ByteBuffer truncated = full.duplicate(); truncated.limit(full.position() + 3); // cut mid-value
// after
ByteBuffer ok = full.duplicate(); ok.limit(full.position() + sizeOfSerializedCollection);
Defensive patterns

Strategy: validation

Validate before calling

public static void checkNotTruncated(ByteBuffer buf, int minBytes) {
    if (buf == null || buf.remaining() < minBytes)
        throw new MarshalException("expected at least " + minBytes + " bytes, got " + (buf == null ? 0 : buf.remaining()));
}

Type guard

public static boolean hasEnoughBytes(ByteBuffer buf, int min) {
    return buf != null && buf.remaining() >= min;
}

Try / catch

try {
    Object value = serializer.deserialize(buffer);
} catch (MarshalException e) {
    if (e.getMessage().startsWith("Not enough bytes")) {
        logger.error("Truncated collection value");
    }
}

Prevention

When it happens

Trigger: deserialize/validate called with a buffer shorter than count * element sizes — truncated network frames, partially written SSTable bytes, or a count prefix that overstates the number of elements.

Common situations: Slicing ByteBuffers incorrectly (wrong position/limit) before deserializing; corrupted data files; reading a collection value with a stale cell size after schema/version mismatch.

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/f1a172a3c0a2785e. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/serializers/CollectionSerializer.java:104

            List<V> values = new ArrayList<>(Math.min(elements, 256));
            int offset = sizeOfCollectionSize();

            for (int i = 0; i < elements; i++)
            {
                V value = readValue(input, accessor, offset);
                offset += sizeOfValue(value, accessor);

                values.add(value);
            }

            if (!accessor.isEmptyFromOffset(input, offset))
                throw new MarshalException("Unexpected extraneous bytes after " + getCollectionName() + " value");

            return values;
        }
        catch (BufferUnderflowException | IndexOutOfBoundsException e)
        {
            throw new MarshalException("Not enough bytes to read a " + getCollectionName());
        }
    }

    /**
     * Return the collection name for error messages.
     * @return the collection name for error messages.
     */
    private String getCollectionName()
    {
        return toLowerCaseLocalized(getType().getSimpleName());
    }

    /**
     * Returns the size of the collections from the number of serialized elements.
     *
     * @param <E> the value type, ByteBuffer or byte[]
     * @param elements the serialized elements
     * @return the size of the collections from the number of serialized elements.

View on GitHub (pinned to 88fd0f6a0e)