{"record":{"id":"4aba124e88f74679","repo":"apache/cassandra","slug":"transfer-of-stream-s-already-completed-or-aborted","errorCode":null,"errorMessage":"Transfer of stream %s already completed or aborted (perhaps session failed?).","messagePattern":"Transfer of stream (.+?) already completed or aborted \\(perhaps session failed\\?\\)\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/streaming/messages/OutgoingStreamMessage.java","lineNumber":105,"sourceCode":"        stream.write(session, out, version);\n    }\n\n    @VisibleForTesting\n    public synchronized void finishTransfer()\n    {\n        transferring = false;\n        //session was aborted mid-transfer, now it's safe to release\n        if (completed)\n        {\n            stream.finish();\n        }\n    }\n\n    @VisibleForTesting\n    public synchronized void startTransfer()\n    {\n        if (completed)\n            throw new RuntimeException(String.format(\"Transfer of stream %s already completed or aborted (perhaps session failed?).\",\n                                                     stream));\n        transferring = true;\n    }\n\n    public synchronized void complete()\n    {\n        if (!completed)\n        {\n            completed = true;\n            //release only if not transferring\n            if (!transferring)\n            {\n                stream.finish();\n            }\n        }\n    }\n\n    @Override","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/streaming/messages/OutgoingStreamMessage.java#L87-L123","documentation":"OutgoingStreamMessage tracks per-stream lifecycle state (transferring/completed/aborted) with synchronized methods. startTransfer throws RuntimeException if the stream is already marked completed, meaning serialize was invoked on a stream whose transfer had already finished or been aborted — usually because the session failed and retried sending the same stream without resetting its state.","triggerScenarios":"A StreamSession retries or re-serializes an OutgoingStreamMessage after the stream was completed()/aborted(); concurrent send attempts on the same stream; a failed session whose streams are re-sent by a higher-level retry loop.","commonSituations":"Streaming retry after a network failure where session state was not fully reset; repair retries racing with stream completion; internal concurrency bugs where complete() and startTransfer() interleave across channels.","solutions":["Recreate the stream session instead of retrying the same stream objects: re-run the repair/bootstrap operation so fresh OutgoingStream instances are created","Check logs for the earlier session failure/abort that completed the stream and address that root cause (network, timeouts)","Upgrade to a version with session retry-state fixes if retries are producing this repeatedly","Avoid manually invoking transfer/serialize on the same OutgoingStreamMessage concurrently (e.g. in tests/tools)"],"exampleFix":"// before: reusing old stream after failure\nsession.send(oldStreamMessage);\n// after: let the session rebuild streams\nStreamResult result = streamPlan.execute(); // new session, new streams","handlingStrategy":"validation","validationCode":"if (streamMessage.isCompleted()) throw new IllegalStateException(\"cannot resend completed stream \" + streamMessage);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never reuse OutgoingStreamMessage objects across session retries; rebuild streams per attempt","Avoid invoking transfer/serialize concurrently on the same stream (tests/tools)","Fix the underlying session failure rather than blind-retrying the same stream"],"tags":["streaming","state","concurrency"],"backgroundTag":"invalid-state-transition","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}