apache/cassandra · error · IllegalStateException

is currently joining the CMS,

Error message

 is currently joining the CMS, 

What it means

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.

Solutions

  1. Wait until the node's join has completed, then retry the leave command.
  2. If the join is stuck, cancel/restart the join process instead of calling leave.
  3. Check node state first (joining vs full member) before invoking leave.

Example fix

// before
cms.commit(new Leave(nodeId));
// after
if (ClusterMetadata.current().joiningMembers.contains(nodeId)) throw new IllegalStateException("wait for join to complete");
cms.commit(new Leave(nodeId));
Defensive patterns

Strategy: validation

Validate before calling

if (ClusterMetadata.current().joiningMembers.contains(nodeId)) throw new IllegalStateException("node still joining; wait for join to complete before leave");

Try / catch

try { cms.commit(new Leave(id)); } catch (IllegalStateException e) { logger.warn("leave rejected: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling leave(NodeId) for a node id present in joiningMembers but not in fullMembers.

Common situations: Decommissioning a node that is mid-join to the CMS, or operator scripts firing CMS_Leave while bootstrap is still in progress.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/93d7e92be8abbeee. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/tcm/CMSMembership.java:170

            throw new IllegalStateException(id + " has already fully joined the CMS");

        return new CMSMembership(lastModified, fullMembers, joiningMembers.without(id));
    }

    public CMSMembership finishJoining(NodeId id)
    {
        if (!joiningMembers.contains(id))
            throw new IllegalStateException(id + " is not currently joining the CMS");
        if (fullMembers.contains(id))
            throw new IllegalStateException(id + " has already fully joined the CMS");

        return new CMSMembership(lastModified, fullMembers.with(id), joiningMembers.without(id));
    }

    public CMSMembership leave(NodeId id)
    {
        if (joiningMembers.contains(id))
            throw new IllegalStateException(id + " is currently joining the CMS, ");
        if (!fullMembers.contains(id))
            throw new IllegalStateException(id + " is not a CMS member");

        return new CMSMembership(lastModified, fullMembers.without(id), joiningMembers);
    }

    @Override
    public String toString()
    {
        return "CMSMembership{" +
               "lastModified=" + lastModified +
               ", fullMembers=" + fullMembers +
               ", joiningMembers=" + joiningMembers +
               '}';
    }

    @Override
    public final boolean equals(Object o)

View on GitHub (pinned to 88fd0f6a0e)