apache/cassandra · error · IllegalArgumentException
Native protocol version
Error message
Native protocol version %d supports up to 65535 elements in any collection - but collection contains %d elements
What it means
The driver's CodecUtils.writeSize serializes collection cardinality in native protocol V1/V2 with a 16-bit element count. If a collection being encoded (a Set, List, or Map argument bound to a statement) contains more than 65535 elements, the short counter would overflow, so pack throws IllegalArgumentException for protocol versions 1 and 2.
Solutions
- Upgrade the native protocol version to V3 or higher (set with-clients/Cluster.builder().withProtocolVersion(ProtocolVersion.V4))
- Split the data into multiple statements with collections under 65,535 elements each
- Model very large datasets in rows rather than one oversized collection column
Example fix
// before cluster.builder().withProtocolVersion(ProtocolVersion.V2); // big collections rejected // after cluster.builder().withProtocolVersion(ProtocolVersion.V4); // supports 32-bit collection sizes
Defensive patterns
Strategy: validation
Validate before calling
if (collection.size() > 65535 && clusterConfiguration.getProtocolVersion().compareTo(ProtocolVersion.V3) < 0) {
throw new IllegalArgumentException("split collection: V1/V2 supports max 65535 elements");
} Try / catch
try {
session.execute(boundStatement);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("65535 elements")) {
// chunk the collection and retry per chunk
}
} Prevention
- Run protocol V3 or higher unless a legacy cluster forces otherwise
- Chunk collections before binding when sizes are unbounded
- Keep collection cardinality bounded by design (e.g. time-partitioned rows)
When it happens
Trigger: Binding a Java collection with more than 65,535 entries (e.g. a huge List<Integer> or Map) to a statement executed with protocolVersion V1 or V2 explicitly set in the cluster configuration.
Common situations: Legacy clusters pinned to protocol V1/V2; batch inserts built as giant collection arguments; migrating code from V3+ protocol assumptions to older clients.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- Native protocol version
- Invalid type for element, expecting but got
- Numeric literals for DATE must be between 0 and
- All values must be either negative or positive, got
- Attempted to encode a response with an unset stream id:
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/0b15dccc7e7cd564.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/functions/types/CodecUtils.java:102
}
}
/**
* Utility method that writes a size value. Mainly intended for collection codecs when serializing
* CQL collections.
*
* @param output The ByteBuffer to write to.
* @param size The collection size.
* @param version The protocol version to use.
*/
private static void writeSize(ByteBuffer output, int size, ProtocolVersion version)
{
switch (version)
{
case V1:
case V2:
if (size > 65535)
throw new IllegalArgumentException(
String.format(
"Native protocol version %d supports up to 65535 elements in any collection - but collection contains %d elements",
version.asInt(), size));
output.putShort((short) size);
break;
case V3:
case V4:
case V5:
case V6:
output.putInt(size);
break;
default:
throw new IllegalArgumentException(String.valueOf(version));
}
}
/**
* Utility method that reads a value. Mainly intended for collection codecs when deserializing CQLView on GitHub (pinned to 88fd0f6a0e)