{"record":{"id":"7a57454d80bb6448","repo":"apache/cassandra","slug":"could-not-perform-next-step-of-joining-the-ring-s","errorCode":null,"errorMessage":"Could not perform next step of joining the ring %s, restart this node and inflight operations will attempt to complete. If no progress is made, cancel the join process for this node and retry","messagePattern":"Could not perform next step of joining the ring (.+?), restart this node and inflight operations will attempt to complete\\. If no progress is made, cancel the join process for this node and retry","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/StorageService.java","lineNumber":1119,"sourceCode":"                                            \"If no progress is made, cancel the join process for this node and retry\");\n        }\n\n        if (sequence.kind() == MultiStepOperation.Kind.REPLACE && sequence.nextStep() != Transformation.Kind.MID_REPLACE)\n            throw new IllegalStateException(\"Can not finish joining ring, sequence is in an incorrect state. \" +\n                                            \"If no progress is made, cancel the join process for this node and retry\");\n\n        // Create a temporary new copy of the sequence with the finishJoining flag set to true and with streaming\n        // disabled, then execute its next step (the MID_*). We do this because effectively we want to jump over the\n        // MID_JOIN/MID_REPLACE of the \"real\" sequence. Note, this does not replace the existing sequence in\n        // ClusterMetadata with the temporary copy, but an effect of executing the MID step of the copy is that it will\n        // update the persisted state of the sequence leaving it with only the FINISH_* step to complete.\n        Transformation.Kind next = sequence.nextStep();\n        boolean success = (sequence instanceof BootstrapAndJoin)\n                          ? ((BootstrapAndJoin)sequence).finishJoiningRing().executeNext().isContinuable()\n                          : ((BootstrapAndReplace)sequence).finishJoiningRing().executeNext().isContinuable();\n\n        if (!success)\n            throw new RuntimeException(String.format(\"Could not perform next step of joining the ring %s, \" +\n                                                     \"restart this node and inflight operations will attempt to complete. \" +\n                                                     \"If no progress is made, cancel the join process for this node and retry\",\n                                                     next));\n\n        // Now the MID step has completed and updated the sequence persisted in ClusterMetadata, finish it.\n        InProgressSequences.finishInProgressSequences(id);\n    }\n\n    void doAuthSetup()\n    {\n        doAuthSetup(true);\n    }\n\n    @VisibleForTesting\n    public void doAuthSetup(boolean async)\n    {\n        if (!authSetupCalled.getAndSet(true))\n        {","sourceCodeStart":1101,"sourceCodeEnd":1137,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/StorageService.java#L1101-L1137","documentation":"Thrown by StorageService.finishJoiningRing after executing the MID_JOIN/MID_REPLACE step of the temporary finishJoining copy of the sequence: if executeNext() does not return a continuable result, the join could not advance and the RuntimeException is thrown naming the step that failed. This indicates the cluster could not apply the transformation needed to finish joining, and the operator must let in-flight operations retry or cancel the join.","triggerScenarios":"finishJoiningRing executed the MID_JOIN (BootstrapAndJoin) or MID_REPLACE (BootstrapAndReplace) step but the resulting transformation was not applied successfully (executeNext().isContinuable() == false) — e.g. another node rejected the transformation, cluster metadata moved on, or a concurrent operation conflicts.","commonSituations":"Concurrent topology operations conflicting with the join; the coordinator node for the transformation is down or unreachable; the persisted sequence in ClusterMetadata changed between the check and the execution; network partition during finishjoin.","solutions":["Restart this node — in-flight operations will automatically attempt to complete the join on startup","Check cluster connectivity and that all nodes are up (nodetool status) so transformations can be committed","If no progress is made after restarts, cancel the join process for this node (cancelhandoff / cancel bootstrap) and retry the join from scratch","Inspect logs on this node and the cluster-metadata coordinator for why the MID step transformation failed"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"Transformation.Kind next = sequence.nextStep();\n// ensure cluster is healthy before executing the MID step\nboolean clusterHealthy = StreamSupport.stream(ClusterMetadata.current().dir().members.spliterator(), false)\n    .allMatch(node -> failureDetector.isAlive(node));\nif (!clusterHealthy) throw new IllegalStateException(\"Cluster not fully alive; postpone finishing join of step \" + next);","typeGuard":null,"tryCatchPattern":"try {\n    storageService.finishJoiningRing();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Could not perform next step of joining the ring\")) {\n        logger.warn(\"MID step \" + e.getMessage() + \" failed; restarting node so in-flight ops retry\", e);\n        // schedule restart or retry with backoff\n    } else throw e;\n}","preventionTips":["Ensure all cluster nodes are up and reachable before calling finishjoin","Avoid concurrent topology operations (decommission, rebuild) while finishing a join","On failure, restart the node promptly so in-flight operations retry the step automatically","If retries keep failing, cancel the join and re-bootstrap instead of looping finishjoin"],"tags":["bootstrap","cluster-join","runtime-error","cassandra"],"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-14T11:17:12.474Z"}