{"record":{"id":"0ce5f65dc6409b24","repo":"apache/cassandra","slug":"stream-s-complete-message-can-be-only-received","errorCode":null,"errorMessage":"[Stream #%s] Complete message can be only received by the initiator!","messagePattern":"\\[Stream #(.+?)\\] Complete message can be only received by the initiator!","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/streaming/StreamSession.java","lineNumber":1148,"sourceCode":"    {\n        transfers.get(tableId).complete(sequenceNumber);\n    }\n\n    /**\n     * Check if session is completed on receiving {@code StreamMessage.Type.COMPLETE} message.\n     */\n    public synchronized void complete()\n    {\n        logger.debug(\"[Stream #{}] handling Complete message, state = {}\", planId(), state);\n\n        if (!isFollower) // initiator\n        {\n            initiatorCompleteOrWait();\n        }\n        else // follower\n        {\n            // pre-4.0 nodes should not be connected via streaming, see {@link MessagingService#accept_streaming}\n            throw new IllegalStateException(String.format(\"[Stream #%s] Complete message can be only received by the initiator!\", planId()));\n        }\n    }\n\n    /**\n     * Synchronize both {@link #complete()} and {@link #maybeCompleted()} to avoid racing\n     */\n    private synchronized boolean maybeCompleted()\n    {\n        if (!(receivers.isEmpty() && transfers.isEmpty()))\n            return false;\n\n        // if already executed once, skip it\n        if (maybeCompleted)\n            return true;\n\n        maybeCompleted = true;\n        if (!isFollower) // initiator\n        {","sourceCodeStart":1130,"sourceCodeEnd":1166,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/streaming/StreamSession.java#L1130-L1166","documentation":"In the bidirectional streaming handshake, the Complete message in the 'follower' role path is invalid: only the session initiator may receive/process Complete on this path (pre-4.0 followers are not expected to stream). Receiving Complete as a follower throws this IllegalStateException.","triggerScenarios":"A follower-side StreamSession processing a Complete message where the isInitiator check fails — i.e. a pre-4.0 (legacy) node sending Complete, or a session whose initiator/follower role is mismatched.","commonSituations":"Upgrading clusters where legacy (pre-4.0) nodes attempt streaming against 4.0+ nodes; misconfigured seeds causing wrong session roles; messaging-version negotiation mistakes.","solutions":["Ensure all nodes are Cassandra 4.0+ or that pre-4.0 nodes are excluded from streaming topology changes (upgrade before repair/rebuild).","Check MessagingService.accept_streaming / messaging version negotiation between the peers.","Re-run the streaming operation after all nodes agree on versions; use a new session/planId.","Inspect the planId in logs to identify the peer sending Complete and its Cassandra version."],"exampleFix":"// before\n// legacy node sends Complete to follower session\n// after\n// block streaming from legacy peers\nif (messagingVersion < MessagingService.VERSION_40) {\n    throw new IOException(\"Streaming from pre-4.0 node not supported\");\n}","handlingStrategy":"validation","validationCode":"if (messagingVersion < MessagingService.VERSION_40) { /* disallow streaming with this peer */ }","typeGuard":null,"tryCatchPattern":"try { session.receiveComplete(...); } catch (IllegalStateException e) { if (e.getMessage().contains(\"only received by the initiator\")) { logger.warn(\"Complete from legacy follower peer\"); } else { throw e; } }","preventionTips":["Upgrade all nodes to 4.0+ before running cluster-wide repairs.","Verify streaming messaging-version negotiation between mixed versions.","Prevent legacy nodes from joining streaming topology operations."],"tags":["streaming","version-compatibility","protocol-violation"],"backgroundTag":"incompatible-node-version","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"}