apache/cassandra · warning · IllegalStateException

%s has already fully joined the CMS

Error message

%s has already fully joined the CMS

What it means

In CMSMembership.startJoining, after checking the joining set, it verifies the node is not already in fullMembers; if it is, IllegalStateException is thrown because the node has already fully joined the CMS and starting a join for it is meaningless and would corrupt membership state.

Source

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

        return lastModified;
    }

    public Set<NodeId> joiningMembers()
    {
        return joiningMembers;
    }

    public Set<NodeId> fullMembers()
    {
        return fullMembers;
    }

    public CMSMembership startJoining(NodeId id)
    {
        if (joiningMembers.contains(id))
            throw new IllegalStateException(id + " is already joining the CMS");
        if (fullMembers.contains(id))
            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");

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Query current CMS membership first; if the node already has full membership, skip the join step entirely
  2. Make the join orchestration idempotent: treat 'already fully joined' as a no-op success
  3. Update stale automation state to reflect the node's completed join before issuing further CMS operations
  4. Only cancel/rejoin if you genuinely intend to remove and re-add the node, using cancelJoining/finishJoining transitions in the correct order

Example fix

// before
membership = cms.startJoining(nodeId);
// after
if (!cms.fullMembers().contains(nodeId))
    membership = cms.startJoining(nodeId);
Defensive patterns

Strategy: validation

Validate before calling

if (membership.fullMembers().contains(nodeId)) return; // already joined; skip startJoining

Prevention

When it happens

Trigger: Applying a startJoining transformation for a NodeId present in fullMembers — a join request replayed after successful completion, or an operator/automation re-running the join step after the node already joined.

Common situations: Retry logic that does not check whether the previous join succeeded; re-running bootstrap/CMS-join tooling on an already-joined node; stale orchestration state following an ambiguous command result.

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