{"record":{"id":"86bf74ab7c71382b","repo":"apache/cassandra","slug":"num-tokens-must-be-1","errorCode":null,"errorMessage":"num_tokens must be >= 1","messagePattern":"num_tokens must be >= 1","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/dht/BootStrapper.java","lineNumber":239,"sourceCode":"    public static Collection<Token> getBootstrapTokens(final ClusterMetadata metadata, InetAddressAndPort address) throws ConfigurationException\n    {\n        String allocationKeyspace = DatabaseDescriptor.getAllocateTokensForKeyspace();\n        Integer allocationLocalRf = DatabaseDescriptor.getAllocateTokensForLocalRf();\n        Collection<String> initialTokens = DatabaseDescriptor.getInitialTokens();\n        if (initialTokens.size() > 0 && allocationKeyspace != null)\n            logger.warn(\"manually specified tokens override automatic allocation\");\n\n        // if user specified tokens, use those\n        if (initialTokens.size() > 0)\n        {\n            Collection<Token> tokens = getSpecifiedTokens(metadata, initialTokens);\n            BootstrapDiagnostics.useSpecifiedTokens(address, allocationKeyspace, tokens, DatabaseDescriptor.getNumTokens());\n            return tokens;\n        }\n\n        int numTokens = DatabaseDescriptor.getNumTokens();\n        if (numTokens < 1)\n            throw new ConfigurationException(\"num_tokens must be >= 1\");\n\n        if (allocationKeyspace != null)\n            return allocateTokens(metadata, address, allocationKeyspace, numTokens);\n\n        if (allocationLocalRf != null)\n            return allocateTokens(metadata, address, allocationLocalRf, numTokens);\n\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    {","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/dht/BootStrapper.java#L221-L257","documentation":"BootStrapper.getBootstrapTokens reads num_tokens from DatabaseDescriptor; if configured below 1 the bootstrap cannot allocate any tokens and throws ConfigurationException. This validates cassandra.yaml's num_tokens before token allocation begins.","triggerScenarios":"Starting a node to bootstrap with num_tokens set to 0 or a negative value in cassandra.yaml (or via system property override).","commonSituations":"Hand-edited cassandra.yaml with num_tokens: 0; scripted config generation that computed 0 tokens; copying config templates with placeholders left unexpanded; confusion between num_tokens and allocate_tokens_for_local_replication_factor.","solutions":["Set num_tokens to a positive integer (default 16 in modern versions, 1 for single-token-per-node deployments) in cassandra.yaml and restart bootstrap.","Check for environment/config templating that substituted 0 (e.g. ${NUM_TOKENS} defaulting empty->0).","If using the legacy initial_token path, num_tokens must still be >= 1; ensure it is not disabled via a broken override.","Validate the config before startup with a config-check or by inspecting effective values in the logs."],"exampleFix":"// cassandra.yaml before\nnum_tokens: 0\n// after\nnum_tokens: 16","handlingStrategy":"validation","validationCode":"// Before startup/bootstrap\nint numTokens = Integer.parseInt(config.getOrDefault(\"num_tokens\", \"16\"));\nif (numTokens < 1)\n    throw new IllegalArgumentException(\"num_tokens must be >= 1, got \" + numTokens);","typeGuard":null,"tryCatchPattern":"try { node.bootstrap(); }\ncatch (ConfigurationException e) {\n    if (e.getMessage().contains(\"num_tokens must be >= 1\"))\n        // fix cassandra.yaml and restart\n}\n","preventionTips":["Validate cassandra.yaml values before rollout","Check templating/CI pipelines for variables defaulting to 0","Keep num_tokens at the version default unless intentional","Log effective config at startup and alert on suspicious values"],"tags":["cassandra","configuration","bootstrap","tokens"],"backgroundTag":"invalid-config-value","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"}