apache/cassandra · error · IllegalStateException

is not a CMS member

Error message

 is not a CMS member

What it means

IllegalStateException from CMSMembership.leave: the node id is neither a joining member nor (in the failing branch) a removable full member, so it 'is not a CMS member'. leave() can only be applied to nodes registered in the CMS membership metadata; requesting leave for an unknown/already-removed node is rejected.

Solutions

  1. Verify the node is a full CMS member before committing Leave.
  2. If the node already left, skip the operation (it is a no-op).
  3. Confirm the NodeId is current; re-query ClusterMetadata.directory for the right id.

Example fix

// before
cms.commit(new Leave(nodeId));
// after
if (ClusterMetadata.current().fullMembers.contains(nodeId)) cms.commit(new Leave(nodeId));
Defensive patterns

Strategy: validation

Validate before calling

if (!ClusterMetadata.current().fullMembers.contains(nodeId)) throw new IllegalStateException(nodeId + " is not a CMS member; nothing to leave");

Try / catch

try { cms.commit(new Leave(id)); } catch (IllegalStateException e) { if (e.getMessage().contains("not a CMS member")) return; throw e; }

Prevention

When it happens

Trigger: Calling leave(NodeId) for a node id not contained in fullMembers (already left, never joined, or unknown id).

Common situations: Decommissioning a node that already left the CMS, using a stale NodeId after a re-bootstrap, or typo/mismatch of node ids in operator tooling.

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/fad2713d95ffe524. Report an issue: GitHub.

Appendix: source

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

        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)
    {
        if (!(o instanceof CMSMembership)) return false;

View on GitHub (pinned to 88fd0f6a0e)