{"record":{"id":"57507fe905d020e6","repo":"apache/cassandra","slug":"cannot-replace-with-a-node-that-is-already-bootstr","errorCode":null,"errorMessage":"Cannot replace with a node that is already bootstrapped","messagePattern":"Cannot replace with a node that is already bootstrapped","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/service/StorageService.java","lineNumber":813,"sourceCode":"        if (SystemKeyspace.wasDecommissioned())\n        {\n            if (CassandraRelevantProperties.OVERRIDE_DECOMMISSION.getBoolean())\n            {\n                logger.warn(\"This node was decommissioned, but overriding by operator request.\");\n            }\n            else\n            {\n                throw new ConfigurationException(\"This node was decommissioned and will not rejoin the ring unless cassandra.override_decommission=true has been set, or all existing data is removed and the node is bootstrapped again\");\n            }\n        }\n\n        if (DatabaseDescriptor.getReplaceTokens().size() > 0 || DatabaseDescriptor.getReplaceNode() != null)\n            throw new RuntimeException(\"Replace method removed; use cassandra.replace_address instead\");\n\n        if (isReplacing())\n        {\n            if (SystemKeyspace.bootstrapComplete())\n                throw new RuntimeException(\"Cannot replace with a node that is already bootstrapped\");\n\n            InetAddressAndPort replaceAddress = DatabaseDescriptor.getReplaceAddress();\n            Directory directory = ClusterMetadata.current().directory;\n            if (directory.peerId(replaceAddress) == null || directory.peerState(replaceAddress) != JOINED)\n                throw new RuntimeException(String.format(\"Cannot replace node %s which is not currently joined\", replaceAddress));\n\n            BootstrapAndReplace.checkUnsafeReplace(shouldBootstrap());\n        }\n\n        if (isReplacingSameAddress())\n        {\n            BootstrapAndReplace.gossipStateToHibernate(ClusterMetadata.current(), ClusterMetadata.currentNullable().myNodeId());\n            Gossiper.instance.start(SystemKeyspace.incrementAndGetGeneration(), false);\n        }\n        else\n        {\n            Gossiper.instance.start(SystemKeyspace.incrementAndGetGeneration(),\n                                    ClusterMetadataService.state() != ClusterMetadataService.State.GOSSIP); // only populate local state if not running in gossip mode","sourceCodeStart":795,"sourceCodeEnd":831,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/StorageService.java#L795-L831","documentation":"When starting in replace mode (cassandra.replace_address set), the replacing node must be new: if system tables show bootstrap already completed on this node, replacing would destroy a node that is a legitimate ring member. Cassandra refuses with a RuntimeException.","triggerScenarios":"Calling initServer with cassandra.replace_address configured while SystemKeyspace.bootstrapComplete() returns true — the local node has previously finished bootstrapping.","commonSituations":"Leaving cassandra.replace_address in jvm-server.options after a successful replace and restarting the node; accidentally reusing a bootstrap node's data dir as a replacement.","solutions":["Remove -Dcassandra.replace_address from startup options and restart normally","If a fresh replacement is truly intended, wipe the data directories so bootstrap state is cleared","Verify replace flags are cleared from config before any planned restart"],"exampleFix":"// before\nJVM_OPTS=\"$JVM_OPTS -Dcassandra.replace_address=10.0.0.5\"  # left over\n// after\n# remove the line and restart; node rejoins as itself","handlingStrategy":"validation","validationCode":"if (Boolean.getBoolean(\"cassandra.replace_address\") && SystemKeyspace.bootstrapComplete()) throw new IllegalStateException(\"remove replace flag\");","typeGuard":null,"tryCatchPattern":"try { startNode(); } catch (RuntimeException e) { if (e.getMessage().contains(\"already bootstrapped\")) { /* remove replace_address and restart */ } }","preventionTips":["Remove cassandra.replace_address immediately after a successful replace","Restart nodes only with clean startup flags","Automate post-replace config cleanup"],"tags":["replace","bootstrap","configuration","data-loss"],"backgroundTag":"conflicting-config-options","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"}