apache/cassandra · error · RuntimeException
[Stream # ] Cannot receive PrepareAckMessage for preview…
Error message
[Stream #%s] Cannot receive PrepareAckMessage for preview session
What it means
In a preview (validation-only) streaming session, no data is transferred, so the follower never sends a PrepareAckMessage. prepareAck() throws this RuntimeException if the receiving side of a preview session gets a PrepareAck, since it indicates a protocol violation for preview sessions.
Solutions
- Ensure preview sessions only use preview-aware message flow; check the code path that starts the session sets preview correctly on both ends.
- Verify all cluster nodes run versions supporting preview streaming (4.0+ semantics).
- Re-run the repair as a non-preview (real) incremental repair if data transfer is expected.
- Capture the planId from logs and check the initiating node's repair type (preview vs full).
Example fix
// before
session.prepareAck(new PrepareAckMessage());
// after
if (!session.isPreview()) {
session.prepareAck(new PrepareAckMessage());
} else {
logger.warn("Skipping PrepareAck for preview session {}", session.planId());
} Defensive patterns
Strategy: validation
Validate before calling
if (session.isPreview()) { /* do not send PrepareAckMessage */ } Try / catch
try { session.prepareAck(msg); } catch (RuntimeException e) { if (e.getMessage().contains("preview session")) { logger.warn("PrepareAck on preview session, protocol mismatch"); } else { throw e; } } Prevention
- Use preview-aware repair tooling on all nodes.
- Keep the cluster on versions that support preview streaming.
- Audit repair commands so preview vs full repairs are not mixed.
When it happens
Trigger: messageReceived dispatching a PrepareAckMessage to a StreamSession where isPreview() is true — i.e. the peer sent a prepare-ack as if this were a real data session.
Common situations: Incremental repair preview (preview parent repair sessions) interacting with peers; mixed-version clusters where one side doesn't honor preview semantics; a bug causing preview sessions to run the full prepare/ack handshake.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot send stream data messages for preview streaming…
- [Stream # ] Cannot receive files for preview session
- An incremental repair with session id
- Stream failed: \nSession peer
- [Stream # ] Complete message can be only received by the…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/8602abee5b980c4e.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/streaming/StreamSession.java:862
{
for (StreamSummary summary : msg.summaries)
prepareReceiving(summary);
// only send the (final) ACK if we are expecting the peer to send this node (the initiator) some files
if (!isPreview())
sendControlMessage(new PrepareAckMessage()).syncUninterruptibly();
}
if (isPreview())
completePreview();
else
startStreamingFiles(PrepareDirection.ACK);
}
private void prepareAck(PrepareAckMessage msg)
{
if (isPreview())
throw new RuntimeException(String.format("[Stream #%s] Cannot receive PrepareAckMessage for preview session", planId()));
startStreamingFiles(PrepareDirection.ACK);
}
protected Future<?> sendControlMessage(StreamMessage message)
{
return channel.sendControlMessage(message);
}
private void processStreamRequests(Collection<StreamRequest> requests)
{
List<StreamRequest> rejectedRequests = new ArrayList<>();
// group requests by keyspace
Multimap<String, StreamRequest> requestsByKeyspace = ArrayListMultimap.create();
requests.forEach(r -> requestsByKeyspace.put(r.keyspace, r));
requestsByKeyspace.asMap().forEach((ks, reqs) ->
{View on GitHub (pinned to 88fd0f6a0e)