{"record":{"id":"67995a60fc31dbf9","repo":"apache/cassandra","slug":"cannot-send-stream-data-messages-for-preview-strea","errorCode":null,"errorMessage":"Cannot send stream data messages for preview streaming sessions","messagePattern":"Cannot send stream data messages for preview streaming sessions","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/streaming/async/StreamingMultiplexedChannel.java","lineNumber":219,"sourceCode":"            return sendMessage(controlChannel, message);\n        }\n        catch (Exception e)\n        {\n            close();\n            session.onError(e);\n            return ImmediateFuture.failure(e);\n        }\n\n    }\n    public Future<?> sendMessage(StreamingChannel channel, StreamMessage message)\n    {\n        if (closed)\n            throw new RuntimeException(\"stream has been closed, cannot send \" + message);\n\n        if (message instanceof OutgoingStreamMessage)\n        {\n            if (session.isPreview())\n                throw new RuntimeException(\"Cannot send stream data messages for preview streaming sessions\");\n            if (logger.isDebugEnabled())\n                logger.debug(\"{} Sending {}\", createLogTag(session), message);\n\n            InetAddressAndPort connectTo = factory.supportsPreferredIp() ? SystemKeyspace.getPreferredIP(to) : to;\n            return fileTransferExecutor.submit(new FileStreamTask((OutgoingStreamMessage) message, connectTo));\n        }\n\n        try\n        {\n            Future<?> promise = channel.send(outSupplier -> {\n                // we anticipate that the control messages are rather small, so allocating a ByteBuf shouldn't  blow out of memory.\n                long messageSize = serializedSize(message, messagingVersion);\n                if (messageSize > 1 << 30)\n                {\n                    throw new IllegalStateException(format(\"%s something is seriously wrong with the calculated stream control message's size: %d bytes, type is %s\",\n                                                           createLogTag(session, controlChannel.id()), messageSize, message.type));\n                }\n                try (StreamingDataOutputPlus out = outSupplier.apply((int) messageSize))","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/streaming/async/StreamingMultiplexedChannel.java#L201-L237","documentation":"Preview streaming sessions transfer no data. In StreamingMultiplexedChannel.sendMessage(), any OutgoingStreamMessage (file data) sent while session.isPreview() is true throws this RuntimeException, enforcing that preview sessions only carry control messages.","triggerScenarios":"sendMessage() called with an OutgoingStreamMessage from a StreamSession where isPreview() is true — a preview session attempting to stream file data (via sendControlMessage path or session stream-file start).","commonSituations":"Repair initiated as preview on one node but requesting data transfer on another (flag mismatch); a preview session erroneously entering startStreamingFiles data path; mixed-version clusters mishandling preview flag.","solutions":["Ensure the session's preview flag is consistently set on both initiator and follower; fix the repair/validate invocation.","Guard the sending code: only start file transfers for non-preview sessions (check isPreview() before submitting FileStreamTask).","Run a real repair or rebuild if data movement is actually required.","Confirm all nodes run a Cassandra version with consistent preview-session semantics."],"exampleFix":"// before\nchannel.sendMessage(streamingChannel, outgoingStreamMessage); // throws for preview\n// after\nif (!session.isPreview()) {\n    channel.sendMessage(streamingChannel, outgoingStreamMessage);\n} else {\n    logger.warn(\"Skipping data send for preview session {}\", session.planId());\n}","handlingStrategy":"validation","validationCode":"if (message instanceof OutgoingStreamMessage && session.isPreview()) { /* skip data send */ }","typeGuard":null,"tryCatchPattern":"try { channel.sendMessage(streamingChannel, msg); } catch (RuntimeException e) { if (e.getMessage().contains(\"preview streaming sessions\")) { logger.warn(\"Data send blocked for preview session\"); } else { throw e; } }","preventionTips":["Gate all file-transfer submission on !session.isPreview().","Use real repairs when data movement is intended.","Keep repair/validate flags consistent across all nodes."],"tags":["streaming","preview","repair","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"}