apache/cassandra · error · IllegalStateException

channel's transferring state is currently set to true. refus

Error message

channel's transferring state is currently set to true. refusing to start new stream

What it means

NettyStreamingChannel multiplexes stream transfers over one connection, using a TRANSFERRING_FILE_ATTR flag to guarantee only one outbound transfer at a time. acquireOut() uses compareAndSet(false, true); if the flag is already true, another transfer holds the channel, and it throws this IllegalStateException rather than interleaving transfers.

Source

Thrown at src/java/org/apache/cassandra/streaming/async/NettyStreamingChannel.java:131

    {
        return peer();
    }

    @Override
    public boolean connected()
    {
        return channel.isOpen();
    }

    public StreamingDataInputPlus in()
    {
        return in;
    }

    public StreamingDataOutputPlus acquireOut()
    {
        if (!channel.attr(TRANSFERRING_FILE_ATTR).compareAndSet(false, true))
            throw new IllegalStateException("channel's transferring state is currently set to true. refusing to start new stream");

        return new AsyncStreamingOutputPlus(channel)
        {
            @Override
            public void close() throws IOException
            {
                try
                {
                    super.close();
                }
                finally
                {
                    NettyStreamingChannel.this.channel.attr(TRANSFERRING_FILE_ATTR).set(FALSE);
                }
            }
        };
    }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Ensure acquireOut() results are always closed (try-with-resources) so TRANSFERRING_FILE_ATTR resets; look for leaked transfers on the channel.
  2. Reduce streaming concurrency (stream_throughput_outbound, concurrent stream sessions) so fewer transfers contend per channel.
  3. Check for stuck prior transfers (long-running FileStreamTask) to the peer and cancel/retry the session.
  4. Upgrade to a version where channel acquisition is queued rather than failing hard, or retry the stream session after the current transfer completes.

Example fix

// before
StreamingDataOutputPlus out = channel.acquireOut();
out.write(...);
// flag may stay set on exception
// after
try (StreamingDataOutputPlus out = channel.acquireOut()) {
    out.write(...);
} // close() resets TRANSFERRING_FILE_ATTR
Defensive patterns

Strategy: try-catch

Validate before calling

if (channel.attr(TRANSFERRING_FILE_ATTR).get()) { /* wait or pick another channel */ }

Try / catch

try (StreamingDataOutputPlus out = channel.acquireOut()) { out.write(...); } catch (IllegalStateException e) { if (e.getMessage().contains("transferring state")) { retryAfterCurrentTransfer(); } else { throw e; } }

Prevention

When it happens

Trigger: Calling acquireOut() on a NettyStreamingChannel that already has an active transfer — e.g. submitting a second FileStreamTask on the same channel while a file is still being transferred, or a leak where a previous transfer never released the flag (close not called).

Common situations: High streaming concurrency saturating the per-session channel pool; an earlier transfer aborted by exception without closing the AsyncStreamingOutputPlus (flag never reset); simultaneous repairs/streams hitting the same peer.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/56081a0eddbb7d9c. Report an issue: GitHub.