apache/cassandra · error · RuntimeException

Cannot send stream data messages for preview streaming…

Error message

Cannot send stream data messages for preview streaming sessions

What it means

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.

Solutions

  1. Ensure the session's preview flag is consistently set on both initiator and follower; fix the repair/validate invocation.
  2. Guard the sending code: only start file transfers for non-preview sessions (check isPreview() before submitting FileStreamTask).
  3. Run a real repair or rebuild if data movement is actually required.
  4. Confirm all nodes run a Cassandra version with consistent preview-session semantics.

Example fix

// before
channel.sendMessage(streamingChannel, outgoingStreamMessage); // throws for preview
// after
if (!session.isPreview()) {
    channel.sendMessage(streamingChannel, outgoingStreamMessage);
} else {
    logger.warn("Skipping data send for preview session {}", session.planId());
}
Defensive patterns

Strategy: validation

Validate before calling

if (message instanceof OutgoingStreamMessage && session.isPreview()) { /* skip data send */ }

Try / catch

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; } }

Prevention

When it happens

Trigger: 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).

Common situations: 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.

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/67995a60fc31dbf9. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/streaming/async/StreamingMultiplexedChannel.java:219

            return sendMessage(controlChannel, message);
        }
        catch (Exception e)
        {
            close();
            session.onError(e);
            return ImmediateFuture.failure(e);
        }

    }
    public Future<?> sendMessage(StreamingChannel channel, StreamMessage message)
    {
        if (closed)
            throw new RuntimeException("stream has been closed, cannot send " + message);

        if (message instanceof OutgoingStreamMessage)
        {
            if (session.isPreview())
                throw new RuntimeException("Cannot send stream data messages for preview streaming sessions");
            if (logger.isDebugEnabled())
                logger.debug("{} Sending {}", createLogTag(session), message);

            InetAddressAndPort connectTo = factory.supportsPreferredIp() ? SystemKeyspace.getPreferredIP(to) : to;
            return fileTransferExecutor.submit(new FileStreamTask((OutgoingStreamMessage) message, connectTo));
        }

        try
        {
            Future<?> promise = channel.send(outSupplier -> {
                // we anticipate that the control messages are rather small, so allocating a ByteBuf shouldn't  blow out of memory.
                long messageSize = serializedSize(message, messagingVersion);
                if (messageSize > 1 << 30)
                {
                    throw new IllegalStateException(format("%s something is seriously wrong with the calculated stream control message's size: %d bytes, type is %s",
                                                           createLogTag(session, controlChannel.id()), messageSize, message.type));
                }
                try (StreamingDataOutputPlus out = outSupplier.apply((int) messageSize))

View on GitHub (pinned to 88fd0f6a0e)