{"record":{"id":"1fd685271d186015","repo":"apache/cassandra","slug":"bootstrapping-to-existing-token-tokenstring","errorCode":null,"errorMessage":"Bootstrapping to existing token \" + tokenString + \" is not allowed (decommission/removenode the old node first).","messagePattern":"Bootstrapping to existing token \" \\+ tokenString \\+ \" is not allowed \\(decommission/removenode the old node first\\)\\.","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/dht/BootStrapper.java","lineNumber":264,"sourceCode":"\n        if (numTokens == 1)\n            logger.warn(\"Picking random token for a single vnode.  You should probably add more vnodes and/or use the automatic token allocation mechanism.\");\n\n        Collection<Token> tokens = getRandomTokens(metadata, numTokens);\n        BootstrapDiagnostics.useRandomTokens(address, metadata, numTokens, tokens);\n        return tokens;\n    }\n\n    private static Collection<Token> getSpecifiedTokens(final ClusterMetadata metadata,\n                                                        Collection<String> initialTokens)\n    {\n        logger.info(\"tokens manually specified as {}\",  initialTokens);\n        List<Token> tokens = new ArrayList<>(initialTokens.size());\n        for (String tokenString : initialTokens)\n        {\n            Token token = metadata.tokenMap.partitioner().getTokenFactory().fromString(tokenString);\n            if (metadata.tokenMap.owner(token) != null)\n                throw new ConfigurationException(\"Bootstrapping to existing token \" + tokenString + \" is not allowed (decommission/removenode the old node first).\");\n            tokens.add(token);\n        }\n        return tokens;\n    }\n\n    static Collection<Token> allocateTokens(final ClusterMetadata metadata,\n                                            InetAddressAndPort address,\n                                            String allocationKeyspace,\n                                            int numTokens)\n    {\n        Keyspace ks = Keyspace.open(allocationKeyspace);\n        if (ks == null)\n            throw new ConfigurationException(\"Problem opening token allocation keyspace \" + allocationKeyspace);\n        AbstractReplicationStrategy rs = ks.getReplicationStrategy();\n\n        Collection<Token> tokens = TokenAllocation.allocateTokens(metadata, rs, address, numTokens);\n        BootstrapDiagnostics.tokensAllocated(address, metadata, allocationKeyspace, numTokens, tokens);\n        return tokens;","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/dht/BootStrapper.java#L246-L282","documentation":"When initial tokens are manually specified (initial_token in cassandra.yaml), getSpecifiedTokens checks the token ring: if another node already owns the requested token, bootstrapping would duplicate ownership, so ConfigurationException is thrown telling the operator to decommission or removenode the old owner first.","triggerScenarios":"Bootstrap with initial_token containing a token already owned by an existing node in metadata.tokenMap; re-adding a node with its old initial_token after it was replaced without removing the old ownership; cloning a node's cassandra.yaml without changing initial_token.","commonSituations":"Node replacement workflows where removenode was skipped; copying config between nodes; resurrecting a failed node into a cluster that already reassigned its tokens; test clusters cloned from snapshots.","solutions":["Run nodetool removenode <host_id> for the node that owns the token (or decommission it) before bootstrapping with that token.","Choose a different, unowned initial_token value for the new node.","If the old node died irrecoverably, use removenode with its host id (found via nodetool status) to purge its tokens.","Remove initial_token entirely and let the allocator pick free tokens automatically.","For node replacement, follow the replace-address workflow (cassandra.replace_address_first_boot) instead of reusing initial_token."],"exampleFix":"// cassandra.yaml before (token already owned)\ninitial_token: -9223372036854775808\n// after\ninitial_token:  # empty -> auto-allocate unowned tokens","handlingStrategy":"validation","validationCode":"// Before bootstrapping with initial_token\nToken t = metadata.tokenMap.partitioner().getTokenFactory().fromString(initialToken);\nif (metadata.tokenMap.owner(t) != null)\n    throw new IllegalStateException(\"Token already owned by \" + metadata.tokenMap.owner(t));","typeGuard":null,"tryCatchPattern":"try { node.bootstrap(); }\ncatch (ConfigurationException e) {\n    if (e.getMessage().contains(\"Bootstrapping to existing token\"))\n        // removenode the old owner or pick a fresh token\n}\n","preventionTips":["Always run nodetool removenode before re-adding a node's token","Never copy initial_token between nodes in cassandra.yaml","Prefer auto token allocation over manual initial_token","Use replace_address workflow for node replacement instead of token reuse"],"tags":["cassandra","bootstrap","tokens","configuration-conflict"],"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"}