apache/cassandra · warning
CMS Membership differ
Error message
CMS Membership differ: {} != {} What it means
ClusterMetadata logs a warning when the cmsMembership set (the nodes currently forming the Cluster Metadata Service) differs between two ClusterMetadata instances. This is part of the metadata diff diagnostics helper used to spot membership disagreement between replicas.
Solutions
- Ensure the node fetches the latest log from CMS so its membership view catches up (`nodetool cms show` to inspect).
- Wait for any in-progress join/leave transformation to commit on all replicas.
- Run `nodetool cms reconfigure` if CMS placement/membership is genuinely wrong.
- Restart the lagging node to force metadata re-initialization from the CMS if it remains stale.
Defensive patterns
Strategy: validation
Validate before calling
if (!local.cmsMembership().equals(remote.cmsMembership())) logger.warn("CMS membership stale; fetch log from CMS before proceeding"); Prevention
- Catch nodes up to the latest epoch before membership-sensitive operations
- Avoid simultaneous joins/leaves
- Run nodetool cms reconfigure after membership mistakes
When it happens
Trigger: Comparing ClusterMetadata instances where the CMS membership sets differ, e.g. after a join/leave/decommission that was applied on one node but not another.
Common situations: Concurrent node joins/leaves; a node that missed membership transformation entries; debugging why quorum operations fail or why gossip-applied metadata is rejected.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Could not remove node
- Extensions differ: !=
- In progress sequences differ
- Initiator directory different from our
- Last modified differ
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/2add22c1c9916d98.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/tcm/ClusterMetadata.java:1275
{
logger.warn("Placements differ:");
placements.dumpDiff(other.placements);
}
if (!lockedRanges.equals(other.lockedRanges))
{
logger.warn("Locked ranges differ: {} != {}", lockedRanges, other.lockedRanges);
}
if (!inProgressSequences.equals(other.inProgressSequences))
{
logger.warn("In progress sequences differ: {} != {}", inProgressSequences, other.inProgressSequences);
}
if (!extensions.equals(other.extensions))
{
logger.warn("Extensions differ: {} != {}", extensions, other.extensions);
}
if (!cmsMembership.equals(other.cmsMembership))
{
logger.warn("CMS Membership differ: {} != {}", cmsMembership, other.cmsMembership);
}
}
@Override
public int hashCode()
{
return Objects.hash(epoch, schema, directory, tokenMap, placements, accordFastPath, lockedRanges, inProgressSequences, consensusMigrationState, accordStaleReplicas, extensions, cmsMembership);
}
public static ClusterMetadata current()
{
return ClusterMetadataService.instance().metadata();
}
public static void checkIdentifier(int remoteIdentifier)
{
ClusterMetadata metadata = currentNullable();
if (metadata != null)View on GitHub (pinned to 88fd0f6a0e)