apache/cassandra · error · NotCMSException
Not currently a member of the CMS, can't commit
Error message
Not currently a member of the CMS, can't commit
What it means
Commit.doVerb handles incoming commit requests on a CMS member. Before processing, checkCMSState() verifies the node is actually part of the CMS. If the node's CMS state is REMOTE — meaning CMS membership lives elsewhere — it throws NotCMSException with this message instead of attempting a Paxos commit it is not entitled to make.
Solutions
- Refresh CMS placement info: run nodetool cms show / awaitClusterMetadata to learn the current CMS members and route commits there
- Let ClusterMetadataService re-discover the CMS (the caller typically retries against the new CMS members after this exception)
- Ensure the messaging/cache layer isn't pinning stale CMS addresses — restart the misrouted node or clear cached placements if needed
- During CMS migration, pause topology operations until the placement change is fully enacted
Example fix
// before: committing without checking local CMS membership
ClusterMetadataService.instance.commit(transform, onSuccess, onFailure);
// after: only commit when this node can act as CMS, otherwise refresh placement and retry
if (ClusterMetadataService.instance.getState().equals(CMSState.REMOTE))
{
// ask the actual CMS members instead, or await placement refresh
ClusterMetadataService.instance.refreshCMSMembership();
throw new NotCMSException("Re-routed: this node is not a CMS member");
}
ClusterMetadataService.instance.commit(transform, onSuccess, onFailure); Defensive patterns
Strategy: retry
Validate before calling
CMSState state = ClusterMetadataService.instance.getState();
if (state == CMSState.REMOTE)
throw new NotCMSException("Refusing to commit: this node is not a CMS member");
if (state == CMSState.GOSSIP)
throw new IllegalStateException("Node in gossip mode; cannot commit"); Type guard
boolean canCommitLocally = () -> {
CMSState s = ClusterMetadataService.instance.getState();
return s == CMSState.LOCAL || s == CMSState.RESET;
}; Try / catch
try
{
commit(entryId, transform, lastKnown, retry);
}
catch (NotCMSException e)
{
// re-resolve current CMS members and retry the commit against them
ClusterMetadataService.instance.refreshCMSMembership();
retryAgainstCurrentCMS();
} Prevention
- Always resolve current CMS membership before sending commit verbs — never cache CMS addresses across topology changes
- Pause commit-producing operations during CMS placement changes
- Monitor for NotCMSException rates to detect routing/membership skew early
- Ensure all nodes run versions that agree on CMS placement discovery (avoid upgrade skew)
When it happens
Trigger: A commit request arrives at a node that previously was (or was thought to be) a CMS member but whose CMS state is now REMOTE, e.g. after CMS re-placement/migration moved CMS to other nodes and stale routing still sends commit verbs here.
Common situations: In-flight commit requests routed to a node right after CMS membership changed; clients or caches holding stale CMS addresses; rolling upgrades during a CMS placement change.
Related errors
- Can not advance in-progress sequence, since its kind is
- Can not apply in-progress sequence, since its kind is
- Could not catch up to epoch
- Could not initialize CMS lookup
- Could not remove from CMS
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/a18fc7c9920db702.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/tcm/Commit.java:420
if (result.isSuccess())
{
Result.Success success = result.success();
replicator.send(success, message.from());
logger.info("Responding with full result {} to sender {}", result, message.from());
}
messagingService.accept(message.responseWith(result), message.from());
}
private void checkCMSState()
{
switch (cmsStateSupplier.get())
{
case RESET:
case LOCAL:
break;
case REMOTE:
throw new NotCMSException("Not currently a member of the CMS, can't commit");
case GOSSIP:
String msg = "Tried to commit when in gossip mode";
logger.error(msg);
throw new IllegalStateException(msg);
default:
throw new IllegalStateException("Illegal state: " + cmsStateSupplier.get());
}
}
}
public interface Replicator
{
Replicator NO_OP = (a,b) -> {};
void send(Result result, InetAddressAndPort source);
}
public static class DefaultReplicator implements Replicator
{View on GitHub (pinned to 88fd0f6a0e)