{"record":{"id":"1f1edd4306a52a38","repo":"apache/cassandra","slug":"cannot-replace-same-address-when-accord-transactio","errorCode":null,"errorMessage":"Cannot replace same address when accord transactions are enabled.","messagePattern":"Cannot replace same address when accord transactions are enabled\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/tcm/Startup.java","lineNumber":689,"sourceCode":"                metadata = ClusterMetadata.current();\n\n                if (metadata.directory.peerState(self) == JOINED)\n                    SystemKeyspace.setBootstrapState(SystemKeyspace.BootstrapState.COMPLETED);\n                else\n                {\n                    StorageService.instance.markBootstrapFailed();\n                    logger.info(\"Did not finish joining the ring; node state is {}, bootstrap state is {}\",\n                                metadata.directory.peerState(self),\n                                SystemKeyspace.getBootstrapState());\n                    break;\n                }\n            case JOINED:\n                if (StorageService.isReplacingSameAddress())\n                {\n                    if (DatabaseDescriptor.getAccordTransactionsEnabled())\n                    {\n                        // TODO (required): we need to support a mode that changes the NodeId when replacing the same address for accord transaction safety\n                        throw new IllegalStateException(\"Cannot replace same address when accord transactions are enabled.\");\n                    }\n\n                    ReplaceSameAddress.streamData(self, metadata, shouldBootstrap, finishJoiningRing);\n                }\n\n                // JOINED appears before BOOTSTRAPPING & BOOT_REPLACE so we can fall\n                // through when we start as REGISTERED/LEFT and complete a full startup\n                logger.info(\"{}\", StorageService.Mode.NORMAL);\n                break;\n            case BOOTSTRAPPING:\n            case BOOT_REPLACING:\n                if (finishJoiningRing)\n                {\n                    throw new IllegalStateException(\"Expected to complete startup sequence, but did not. \" +\n                                                    \"Can't proceed from the state \" + metadata.directory.peerState(self));\n                }\n                break;\n            case LEAVING:","sourceCodeStart":671,"sourceCodeEnd":707,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/Startup.java#L671-L707","documentation":"During TCM-based startup, a node configured with storage_port identical to an existing node's address (replace-address pointing at itself) cannot perform the 'replace same address' operation when Accord transactions are enabled. Accord binds transaction state to a persistent NodeId; reusing the address with the same NodeId would corrupt transaction safety, so the JVM throws IllegalStateException deliberately with a TODO to add a supported mode.","triggerScenarios":"Setting cassandra.replace_address (or replace_address_first_boot) to the node's OWN broadcast address while cassandra.accord.transactions_enabled is true, then starting the node in state JOINED.","commonSituations":"Operators recovering a dead node by pointing replace_address at itself on ephemeral infrastructure (e.g. k8s StatefulSet restarts), combined with a cluster where Accord (distributed transactions) is enabled after an upgrade.","solutions":["Disable Accord transactions (set the accord transactions_enabled property to false) before performing the same-address replacement, then re-enable after the node rejoins","Perform a normal (different-address) replacement, or decommission/removal + fresh bootstrap instead of replace-same-address","Upgrade/pick a Cassandra version that implements the NodeId-change-on-replace mode (the code TODO), if available","If the data on disk is disposable, wipe data dirs and bootstrap as a new node"],"exampleFix":"// before (cassandra.yaml / properties)\ncassandra.replace_address=10.0.0.5   # same as this node\naccord.transactions_enabled=true\n// after\naccord.transactions_enabled=false   # allows ReplaceSameAddress path\n# ... after successful rejoin, re-enable accord.transactions_enabled=true","handlingStrategy":"validation","validationCode":"if (DatabaseDescriptor.isReplacingSameAddress() && DatabaseDescriptor.getAccordTransactionsEnabled())\n    throw new IllegalArgumentException(\"Disable accord transactions or use a different replace address\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check cassandra.replace_address differs from the node's own broadcast address unless Accord is disabled","Keep replacement runbooks aware of the accord.transactions_enabled setting","Test replacement procedures after enabling new features like Accord"],"tags":["accord","tcm","replace-address","startup","configuration"],"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-14T11:17:12.474Z"}