{"record":{"id":"d473075337bbd9e2","repo":"apache/cassandra","slug":"initial-token-was-set-but-num-tokens-is-not","errorCode":null,"errorMessage":"initial_token was set but num_tokens is not!","messagePattern":"initial_token was set but num_tokens is not!","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/config/DatabaseDescriptor.java","lineNumber":1750,"sourceCode":"                    lowestAcceptedValue);\n    }\n\n    public static void applyTokensConfig()\n    {\n        applyTokensConfig(conf);\n    }\n\n    static void applyTokensConfig(Config conf)\n    {\n        if (conf.initial_token != null)\n        {\n            Collection<String> tokens = tokensFromString(conf.initial_token);\n            if (conf.num_tokens == null)\n            {\n                if (tokens.size() == 1)\n                    conf.num_tokens = 1;\n                else\n                    throw new ConfigurationException(\"initial_token was set but num_tokens is not!\", false);\n            }\n\n            if (tokens.size() != conf.num_tokens)\n            {\n                throw new ConfigurationException(String.format(\"The number of initial tokens (by initial_token) specified (%s) is different from num_tokens value (%s)\",\n                                                               tokens.size(),\n                                                               conf.num_tokens),\n                                                 false);\n            }\n\n            for (String token : tokens)\n                partitioner.getTokenFactory().validate(token);\n        }\n        else if (conf.num_tokens == null)\n        {\n            conf.num_tokens = 1;\n        }\n    }","sourceCodeStart":1732,"sourceCodeEnd":1768,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/config/DatabaseDescriptor.java#L1732-L1768","documentation":"When configuring the token ring (applyInitialToken/NumTokens logic), if initial_token is set but num_tokens is absent, Cassandra infers num_tokens only when exactly one token was given; with multiple initial_tokens it cannot guess the intended vnode count and throws this ConfigurationException. The token count must always match num_tokens.","triggerScenarios":"cassandra.yaml defines initial_token (or multiple comma-separated tokens) while num_tokens is omitted, and the number of tokens parsed from initial_token is not exactly 1.","commonSituations":"Operators migrating from single-token setups (pre-1.2 style) or from 3.x 8-vnode defaults paste old initial_token lines into a config without num_tokens; multi-token manual assignments for balanced clusters after a resize.","solutions":["Set num_tokens in cassandra.yaml to match the number of values in initial_token","Or remove initial_token and let Cassandra auto-assign with the configured num_tokens","If you intended a single-token legacy node, keep exactly one token value and num_tokens: 1"],"exampleFix":"// cassandra.yaml before\ninitial_token: tokenA,tokenB,tokenC\n// after\nnum_tokens: 3\ninitial_token: tokenA,tokenB,tokenC","handlingStrategy":"validation","validationCode":"if (conf.initial_token != null) {\n    int n = conf.initial_token.split(\",\").length;\n    if (conf.num_tokens == null ? n != 1 : conf.num_tokens != n)\n        throw new IllegalStateException(\"num_tokens must match initial_token count (\" + n + \")\");\n}","typeGuard":null,"tryCatchPattern":"try { DatabaseDescriptor.daemonInitialization(); } catch (ConfigurationException e) { /* align num_tokens with initial_token */ }","preventionTips":["Prefer num_tokens-only configs and drop initial_token unless manually assigning","Whenever setting initial_token, set num_tokens to the same count","After upgrading, review legacy initial_token leftovers in yaml"],"tags":["cassandra","configuration","tokens"],"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-14T16:17:12.679Z"}