apache/cassandra · error · IllegalStateException

is not currently joining the CMS

Error message

 is not currently joining the CMS

What it means

Thrown by CMSMembership.finishJoining when a node is asked to complete its CMS membership but it is not present in the joiningMembers set. TCM tracks CMS membership in two phases: joining and full members. The state machine requires a node to be in the joining set before finishJoining can promote it.

Solutions

  1. Check the node's current membership state before calling finishJoining (verify it appears in joiningMembers).
  2. Do not retry finishJoining after a successful commit; treat a prior committed transformation as terminal.
  3. If the node already fully joined, no action is needed - remove the duplicate call.

Example fix

// before
metadata.forId(id).finishJoining(id);
// after
if (metadata.fullMembers.contains(id)) { /* already joined, skip */ }
else if (metadata.joiningMembers.contains(id)) { metadata.finishJoining(id); }
Defensive patterns

Strategy: validation

Validate before calling

if (!ClusterMetadata.current().joiningMembers.contains(nodeId)) throw new IllegalStateException(nodeId + " not in joining state; skip finishJoining");

Try / catch

try { membership.finishJoining(id); } catch (IllegalStateException e) { logger.warn("finishJoining skipped: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling finishJoining(NodeId) for a node id that was never added as a joining member, or after it was already promoted to a full member or removed.

Common situations: Replaying a JoinCluster/FinishJoin transformation twice, a retry racing with an already-committed transformation, or operator tooling invoking finishJoining out of order during cluster bootstrap.

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

Appendix: source

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

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

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

    public CMSMembership cancelJoining(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, 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()

View on GitHub (pinned to 88fd0f6a0e)