apache/cassandra · error · IllegalStateException
[Stream # ] Complete message can be only received by the…
Error message
[Stream #%s] Complete message can be only received by the initiator!
What it means
In the bidirectional streaming handshake, the Complete message in the 'follower' role path is invalid: only the session initiator may receive/process Complete on this path (pre-4.0 followers are not expected to stream). Receiving Complete as a follower throws this IllegalStateException.
Solutions
- Ensure all nodes are Cassandra 4.0+ or that pre-4.0 nodes are excluded from streaming topology changes (upgrade before repair/rebuild).
- Check MessagingService.accept_streaming / messaging version negotiation between the peers.
- Re-run the streaming operation after all nodes agree on versions; use a new session/planId.
- Inspect the planId in logs to identify the peer sending Complete and its Cassandra version.
Example fix
// before
// legacy node sends Complete to follower session
// after
// block streaming from legacy peers
if (messagingVersion < MessagingService.VERSION_40) {
throw new IOException("Streaming from pre-4.0 node not supported");
} Defensive patterns
Strategy: validation
Validate before calling
if (messagingVersion < MessagingService.VERSION_40) { /* disallow streaming with this peer */ } Try / catch
try { session.receiveComplete(...); } catch (IllegalStateException e) { if (e.getMessage().contains("only received by the initiator")) { logger.warn("Complete from legacy follower peer"); } else { throw e; } } Prevention
- Upgrade all nodes to 4.0+ before running cluster-wide repairs.
- Verify streaming messaging-version negotiation between mixed versions.
- Prevent legacy nodes from joining streaming topology operations.
When it happens
Trigger: A follower-side StreamSession processing a Complete message where the isInitiator check fails — i.e. a pre-4.0 (legacy) node sending Complete, or a session whose initiator/follower role is mismatched.
Common situations: Upgrading clusters where legacy (pre-4.0) nodes attempt streaming against 4.0+ nodes; misconfigured seeds causing wrong session roles; messaging-version negotiation mistakes.
Related errors
- Cannot send stream data messages for preview streaming…
- [Stream # ] Cannot receive files for preview session
- [Stream # ] Cannot receive PrepareAckMessage for preview…
- A node required to move the data consistently is down
- Can not start range streaming as all candidates
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/0ce5f65dc6409b24.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/streaming/StreamSession.java:1148
{
transfers.get(tableId).complete(sequenceNumber);
}
/**
* Check if session is completed on receiving {@code StreamMessage.Type.COMPLETE} message.
*/
public synchronized void complete()
{
logger.debug("[Stream #{}] handling Complete message, state = {}", planId(), state);
if (!isFollower) // initiator
{
initiatorCompleteOrWait();
}
else // follower
{
// pre-4.0 nodes should not be connected via streaming, see {@link MessagingService#accept_streaming}
throw new IllegalStateException(String.format("[Stream #%s] Complete message can be only received by the initiator!", planId()));
}
}
/**
* Synchronize both {@link #complete()} and {@link #maybeCompleted()} to avoid racing
*/
private synchronized boolean maybeCompleted()
{
if (!(receivers.isEmpty() && transfers.isEmpty()))
return false;
// if already executed once, skip it
if (maybeCompleted)
return true;
maybeCompleted = true;
if (!isFollower) // initiator
{View on GitHub (pinned to 88fd0f6a0e)