{"record":{"id":"93d7e92be8abbeee","repo":"apache/cassandra","slug":"is-currently-joining-the-cms","errorCode":null,"errorMessage":" is currently joining the CMS, ","messagePattern":" is currently joining the CMS, ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tcm/CMSMembership.java","lineNumber":170,"sourceCode":"            throw new IllegalStateException(id + \" has already fully joined the CMS\");\n\n        return new CMSMembership(lastModified, fullMembers, joiningMembers.without(id));\n    }\n\n    public CMSMembership finishJoining(NodeId id)\n    {\n        if (!joiningMembers.contains(id))\n            throw new IllegalStateException(id + \" is not currently joining the CMS\");\n        if (fullMembers.contains(id))\n            throw new IllegalStateException(id + \" has already fully joined the CMS\");\n\n        return new CMSMembership(lastModified, fullMembers.with(id), joiningMembers.without(id));\n    }\n\n    public CMSMembership leave(NodeId id)\n    {\n        if (joiningMembers.contains(id))\n            throw new IllegalStateException(id + \" is currently joining the CMS, \");\n        if (!fullMembers.contains(id))\n            throw new IllegalStateException(id + \" is not a CMS member\");\n\n        return new CMSMembership(lastModified, fullMembers.without(id), joiningMembers);\n    }\n\n    @Override\n    public String toString()\n    {\n        return \"CMSMembership{\" +\n               \"lastModified=\" + lastModified +\n               \", fullMembers=\" + fullMembers +\n               \", joiningMembers=\" + joiningMembers +\n               '}';\n    }\n\n    @Override\n    public final boolean equals(Object o)","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/CMSMembership.java#L152-L188","documentation":"IllegalStateException from CMSMembership.leave: the node id being removed from the cluster is present in fullMembers (not in joiningMembers), so the composed message '<id> is currently joining the CMS, ' prefix is contradicted by state; effectively leave() was invoked on a node whose membership state does not permit the requested transition in the Cluster Metadata Service.","triggerScenarios":"Calling leave(NodeId) for a node id present in joiningMembers but not in fullMembers.","commonSituations":"Decommissioning a node that is mid-join to the CMS, or operator scripts firing CMS_Leave while bootstrap is still in progress.","solutions":["Wait until the node's join has completed, then retry the leave command.","If the join is stuck, cancel/restart the join process instead of calling leave.","Check node state first (joining vs full member) before invoking leave."],"exampleFix":"// before\ncms.commit(new Leave(nodeId));\n// after\nif (ClusterMetadata.current().joiningMembers.contains(nodeId)) throw new IllegalStateException(\"wait for join to complete\");\ncms.commit(new Leave(nodeId));","handlingStrategy":"validation","validationCode":"if (ClusterMetadata.current().joiningMembers.contains(nodeId)) throw new IllegalStateException(\"node still joining; wait for join to complete before leave\");","typeGuard":null,"tryCatchPattern":"try { cms.commit(new Leave(id)); } catch (IllegalStateException e) { logger.warn(\"leave rejected: {}\", e.getMessage()); }","preventionTips":["Ensure decommission starts only after CMS join completes","Poll membership state before issuing leave","Handle mid-join nodes with cancel/restart instead of leave"],"tags":["tcm","cms-membership","invalid-state-transition"],"backgroundTag":"invalid-state-transition","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}