apache/cassandra · error · IllegalStateException
%s something is seriously wrong with the calculated stream c
Error message
%s something is seriously wrong with the calculated stream control message's size: %d bytes, type is %s
What it means
StreamingMultiplexedChannel.sendMessage guards the send path for stream control messages: before allocating a buffer it computes the serialized size of the control message and refuses to send anything larger than 1GB, since control messages are expected to be small. Throwing IllegalStateException here means the calculated serialized size is absurd, indicating a corrupted or pathological message or serialization bug rather than a normal streaming condition.
Source
Thrown at src/java/org/apache/cassandra/streaming/async/StreamingMultiplexedChannel.java:234
if (message instanceof OutgoingStreamMessage)
{
if (session.isPreview())
throw new RuntimeException("Cannot send stream data messages for preview streaming sessions");
if (logger.isDebugEnabled())
logger.debug("{} Sending {}", createLogTag(session), message);
InetAddressAndPort connectTo = factory.supportsPreferredIp() ? SystemKeyspace.getPreferredIP(to) : to;
return fileTransferExecutor.submit(new FileStreamTask((OutgoingStreamMessage) message, connectTo));
}
try
{
Future<?> promise = channel.send(outSupplier -> {
// we anticipate that the control messages are rather small, so allocating a ByteBuf shouldn't blow out of memory.
long messageSize = serializedSize(message, messagingVersion);
if (messageSize > 1 << 30)
{
throw new IllegalStateException(format("%s something is seriously wrong with the calculated stream control message's size: %d bytes, type is %s",
createLogTag(session, controlChannel.id()), messageSize, message.type));
}
try (StreamingDataOutputPlus out = outSupplier.apply((int) messageSize))
{
StreamMessage.serialize(message, out, messagingVersion, session);
}
});
promise.addListener(future -> onMessageComplete(future, message));
return promise;
}
catch (Exception e)
{
close();
session.onError(e);
return ImmediateFuture.failure(e);
}
}
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Reduce the size of the streaming plan: split large repairs/streaming operations into smaller batches so each control message stays well under 1GB
- Verify both nodes run compatible Cassandra versions and messagingVersion so serializedSize calculations match on both sides
- Inspect the message type logged to identify which control message (Prepare/Summary/etc.) is oversized and check its contents for pathological data (huge table counts, many ranges)
- If reproducible with a normal-sized plan, file/inspect for a serializer bug in StreamMessage.serialize size accounting
Example fix
// before: one giant stream plan
StorageService.instance.stream(hugeRangesPerTable);
// after: chunk the requests into bounded batches
for (List<Range<Token>> batch : partition(ranges, MAX_RANGES_PER_PLAN))
StorageService.instance.stream(batch); Defensive patterns
Strategy: validation
Validate before calling
long size = serializedSize(message, messagingVersion);
if (size > (1 << 30)) throw new IllegalArgumentException("stream control message too large: " + size); Prevention
- Keep stream plans small; partition large range/table sets into multiple sessions
- Keep messaging versions aligned across the cluster so size calculations match
- Log message type and size before sending large control messages in custom tooling
When it happens
Trigger: Calling sendControlMessage -> sendMessage with a StreamMessage whose serialized size (computed via serializedSize(message, messagingVersion)) exceeds 1 << 30 bytes; typically caused by a message carrying a huge collection (e.g. a StreamSummary or PrepareMessage listing an enormous number of sessions/streams) or a bug in the serializer's size calculation.
Common situations: Streaming tens of thousands of tables/ranges in a single stream plan so the Prepare/Summary control message balloons past 1GB; version skew where messagingVersion-dependent size calculation disagrees with the peer; driver/internal bugs in StreamMessage.serialize size accounting.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Failed to serialize partition key '%s' on table '%s' in keys
- [Stream {}] Error while reading partition {} from stream on
- [Stream {}] Error while reading partition {} from stream on
- Serialized size must not be more than 2GiB
- Unable to allocate %s
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/c81b241193d63c68.
Report an issue: GitHub.