{"record":{"id":"8602abee5b980c4e","repo":"apache/cassandra","slug":"stream-s-cannot-receive-prepareackmessage-for","errorCode":null,"errorMessage":"[Stream #%s] Cannot receive PrepareAckMessage for preview session","messagePattern":"\\[Stream #(.+?)\\] Cannot receive PrepareAckMessage for preview session","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/streaming/StreamSession.java","lineNumber":862,"sourceCode":"        {\n            for (StreamSummary summary : msg.summaries)\n                prepareReceiving(summary);\n\n            // only send the (final) ACK if we are expecting the peer to send this node (the initiator) some files\n            if (!isPreview())\n                sendControlMessage(new PrepareAckMessage()).syncUninterruptibly();\n        }\n\n        if (isPreview())\n            completePreview();\n        else\n            startStreamingFiles(PrepareDirection.ACK);\n    }\n\n    private void prepareAck(PrepareAckMessage msg)\n    {\n        if (isPreview())\n            throw new RuntimeException(String.format(\"[Stream #%s] Cannot receive PrepareAckMessage for preview session\", planId()));\n        startStreamingFiles(PrepareDirection.ACK);\n    }\n\n    protected Future<?> sendControlMessage(StreamMessage message)\n    {\n        return channel.sendControlMessage(message);\n    }\n\n    private void processStreamRequests(Collection<StreamRequest> requests)\n    {\n        List<StreamRequest> rejectedRequests = new ArrayList<>();\n\n        // group requests by keyspace\n        Multimap<String, StreamRequest> requestsByKeyspace = ArrayListMultimap.create();\n        requests.forEach(r -> requestsByKeyspace.put(r.keyspace, r));\n\n        requestsByKeyspace.asMap().forEach((ks, reqs) ->\n                                           {","sourceCodeStart":844,"sourceCodeEnd":880,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/streaming/StreamSession.java#L844-L880","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nsession.prepareAck(new PrepareAckMessage());\n// after\nif (!session.isPreview()) {\n    session.prepareAck(new PrepareAckMessage());\n} else {\n    logger.warn(\"Skipping PrepareAck for preview session {}\", session.planId());\n}","handlingStrategy":"validation","validationCode":"if (session.isPreview()) { /* do not send PrepareAckMessage */ }","typeGuard":null,"tryCatchPattern":"try { session.prepareAck(msg); } catch (RuntimeException e) { if (e.getMessage().contains(\"preview session\")) { logger.warn(\"PrepareAck on preview session, protocol mismatch\"); } else { throw e; } }","preventionTips":["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."],"tags":["streaming","repair","preview","protocol-violation"],"backgroundTag":"unsupported-operation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}