{"record":{"id":"35e9fc1bb4120ab5","repo":"apache/cassandra","slug":"can-t-abort-bootstrap-for-it-is-alive","errorCode":null,"errorMessage":"Can't abort bootstrap for  - it is alive","messagePattern":"Can't abort bootstrap for  - it is alive","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/StorageService.java","lineNumber":1673,"sourceCode":"            return true;\n        }\n        else\n        {\n            logger.info(\"Resuming bootstrap is requested, but the node is already bootstrapped.\");\n            return false;\n        }\n    }\n\n    public void abortBootstrap(String nodeStr, String endpointStr)\n    {\n        logger.info(\"Aborting bootstrap for {}\", StringUtils.isEmpty(nodeStr) ? endpointStr : nodeStr);\n        ClusterMetadata metadata = ClusterMetadata.current();\n        NodeId nodeId = parseNodeIdOrEndpoint(metadata, nodeStr, endpointStr);\n        InetAddressAndPort endpoint = metadata.directory.endpoint(nodeId);\n        if (endpoint == null)\n            throw new IllegalArgumentException(\"Can't abort bootstrap for \" + nodeId + \" - it does not exist in cluster metadata\");\n        if (Gossiper.instance.isKnownEndpoint(endpoint) && FailureDetector.instance.isAlive(endpoint))\n            throw new RuntimeException(\"Can't abort bootstrap for \" + nodeId + \" - it is alive\");\n        NodeState nodeState = metadata.directory.peerState(nodeId);\n        switch (nodeState)\n        {\n            case REGISTERED:\n            case BOOTSTRAPPING:\n            case BOOT_REPLACING:\n                if (metadata.inProgressSequences.contains(nodeId))\n                {\n                    MultiStepOperation<?> seq = metadata.inProgressSequences.get(nodeId);\n                    if (seq.kind() != MultiStepOperation.Kind.JOIN && seq.kind() != MultiStepOperation.Kind.REPLACE)\n                        throw new RuntimeException(\"Can't abort bootstrap for \" + nodeId + \" since it is not bootstrapping\");\n                    ClusterMetadataService.instance().commit(new CancelInProgressSequence(nodeId));\n                }\n                ClusterMetadataService.instance().commit(new Unregister(nodeId, EnumSet.of(REGISTERED, BOOTSTRAPPING, BOOT_REPLACING), ClusterMetadataService.instance().placementProvider()));\n                break;\n            default:\n                throw new RuntimeException(\"Can't abort bootstrap for node \" + nodeId + \" since the state is \" + nodeState);\n        }","sourceCodeStart":1655,"sourceCodeEnd":1691,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/StorageService.java#L1655-L1691","documentation":"Thrown by StorageService.abortBootstrap when the target node is reachable: the endpoint is known to Gossiper AND the failure detector reports it alive. Bootstrap can only be aborted for nodes that are dead/gone, because a live node participates in its own join protocol and aborting under it would corrupt cluster state.","triggerScenarios":"Running `nodetool abortbootstrap <node>` while the bootstrapping node is up and gossiping - e.g. trying to abort a slow join instead of first stopping the node.","commonSituations":"Operator wants to cancel an in-progress bootstrap but forgets the joining node must be shut down first; failure detector briefly reports the node alive due to gossip lag after a crash; firewall keeps the node pingable while Cassandra is半 down.","solutions":["Stop the joining Cassandra node (systemctl stop cassandra / nodetool drain then stop) and wait for it to be marked down, then re-run abortbootstrap","Verify the node is actually down with `nodetool gossipinfo` and the failure detector before aborting","If the node just died, wait for gossip/phi-convictal timeout so FailureDetector reports it dead","If the node is alive and you want it in the cluster, do not abort - let the bootstrap finish or use maintenance operations instead"],"exampleFix":"// before\nnodetool abortbootstrap 10.0.0.5   # node still running\n// after\nssh 10.0.0.5 'nodetool drain && systemctl stop cassandra'\n# wait until node shows DOWN\nnodetool abortbootstrap 10.0.0.5","handlingStrategy":"validation","validationCode":"// Check the node is DOWN before aborting\n// nodetool gossipinfo | grep <endpoint>  and verify failure-detector state\nboolean alive = /* probe node or check `nodetool status` shows DN */;\nif (alive) throw new IllegalStateException(\"Stop the bootstrapping node first\");","typeGuard":null,"tryCatchPattern":"try {\n    probe.abortBootstrap(nodeId);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"it is alive\"))\n        log.warn(\"Node still alive - stop it and wait for conviction before aborting\");\n    else throw e;\n}","preventionTips":["Stop the joining node and wait for it to show DN in `nodetool status` before aborting","Account for gossip/failure-detector lag after a crash - wait for conviction","Do not use abortbootstrap to cancel a join on a healthy node; let it finish or stop it"],"tags":["nodetool","bootstrap","gossip","failure-detector","node-lifecycle"],"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"}