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

  1. Ensure preview sessions only use preview-aware message flow; check the code path that starts the session sets preview correctly on both ends.
  2. Verify all cluster nodes run versions supporting preview streaming (4.0+ semantics).
  3. Re-run the repair as a non-preview (real) incremental repair if data transfer is expected.
  4. 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

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


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)