{"record":{"id":"4db8faa239367f12","repo":"apache/cassandra","slug":"tokens-must-be-provided-to-force-join-a-node","errorCode":null,"errorMessage":"Tokens must be provided to force join a node.","messagePattern":"Tokens must be provided to force join a node\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tools/CMSOfflineTool.java","lineNumber":687,"sourceCode":"                if (tokens.isEmpty()\n                    || (tokenSet.size() == sequenceTokens.size() && sequenceTokens.containsAll(tokenSet)))\n                {\n                    updatedMetadata = bootstrapAndJoin.applyTo(metadata).success().metadata;\n                }\n                else\n                {\n                    // If tokens are provided, then it should match with the in-progress sequence tokens\n                    throw new IllegalArgumentException(\"The tokens provided \" + tokens + \" do not match with \" +\n                                                       \" in progress BootstrapAndJoin sequence tokens \" +\n                                                       sequenceTokens + \". Cannot proceed further.\");\n                }\n            }\n            else\n            {\n                // There are no in-progress sequences, force join by using UnsafeJoin transformation\n                if (tokenSet.isEmpty())\n                {\n                    throw new IllegalArgumentException(\"Tokens must be provided to force join a node.\");\n                }\n                UnsafeJoin unsafeJoin = new UnsafeJoin(nodeId, tokenSet, new UniformRangePlacement());\n                updatedMetadata = unsafeJoin.execute(metadata).success().metadata;\n            }\n\n            writeMetadata(output, updatedMetadata, outputFilePath);\n        }\n    }\n\n    /**\n     * Prints the full {@code toString()} representation of the cluster metadata to stdout.\n     * Useful for a quick human-readable overview of the entire metadata state.\n     * <p>\n     * <b>Note:</b> The output format is not stable and may change between versions.\n     * Do not rely on it for programmatic parsing.\n     */\n    @Command(name = \"print\", description = \"Prints string output of the cluster metadata. \" +\n                                           \"Output format is subject to change and should not be relied on for parsing.\")","sourceCodeStart":669,"sourceCodeEnd":705,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tools/CMSOfflineTool.java#L669-L705","documentation":"Thrown by ForceJoin when there is no in-progress join sequence for the node and no tokens were supplied. The UnsafeJoin transformation requires an explicit token set to place the node in the ring, so an empty token set is a missing-required-argument error.","triggerScenarios":"Running force join for a node with no inProgressSequences entry and without the --tokens option, so tokenSet is empty when constructing UnsafeJoin.","commonSituations":"First-time force join of a failed bootstrap where the operator forgets that tokens are mandatory; scripts that pass tokens only in some branches; confusing this tool with online CMS commands that can allocate tokens automatically.","solutions":["Provide the token list with --tokens <t1,t2,...> for the node.","Generate appropriate tokens (e.g. with GenerateTokens or the cluster's allocation strategy such as UniformRangePlacement semantics).","If the node has a pending join sequence, omit tokens to resume it instead."],"exampleFix":"// before\n// cms offline force-join --id 3\n// after\n// cms offline force-join --id 3 --tokens -9223372036854775808,0,3074457345618258602","handlingStrategy":"validation","validationCode":"if (metadata.inProgressSequences.get(nodeId) == null && tokenSet.isEmpty())\n    throw new IllegalArgumentException(\"--tokens is required when no join sequence is in progress\");","typeGuard":null,"tryCatchPattern":"try { forceJoin(...); } catch (IllegalArgumentException e) { System.err.println(\"Supply --tokens: \" + e.getMessage()); }","preventionTips":["Always plan tokens before force join","Use GenerateTokens to produce a valid token list","Branch scripts on whether a sequence is in progress"],"tags":["cli","tokens","missing-argument"],"backgroundTag":"missing-required-argument","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"}