{"record":{"id":"a18fc7c9920db702","repo":"apache/cassandra","slug":"not-currently-a-member-of-the-cms-can-t-commit","errorCode":null,"errorMessage":"Not currently a member of the CMS, can't commit","messagePattern":"Not currently a member of the CMS, can't commit","errorType":"exception","errorClass":"NotCMSException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tcm/Commit.java","lineNumber":420,"sourceCode":"            if (result.isSuccess())\n            {\n                Result.Success success = result.success();\n                replicator.send(success, message.from());\n                logger.info(\"Responding with full result {} to sender {}\", result, message.from());\n            }\n\n            messagingService.accept(message.responseWith(result), message.from());\n        }\n\n        private void checkCMSState()\n        {\n            switch (cmsStateSupplier.get())\n            {\n                case RESET:\n                case LOCAL:\n                    break;\n                case REMOTE:\n                    throw new NotCMSException(\"Not currently a member of the CMS, can't commit\");\n                case GOSSIP:\n                    String msg = \"Tried to commit when in gossip mode\";\n                    logger.error(msg);\n                    throw new IllegalStateException(msg);\n                default:\n                    throw new IllegalStateException(\"Illegal state: \" + cmsStateSupplier.get());\n            }\n        }\n    }\n\n    public interface Replicator\n    {\n        Replicator NO_OP = (a,b) -> {};\n        void send(Result result, InetAddressAndPort source);\n    }\n\n    public static class DefaultReplicator implements Replicator\n    {","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/Commit.java#L402-L438","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: committing without checking local CMS membership\nClusterMetadataService.instance.commit(transform, onSuccess, onFailure);\n// after: only commit when this node can act as CMS, otherwise refresh placement and retry\nif (ClusterMetadataService.instance.getState().equals(CMSState.REMOTE))\n{\n    // ask the actual CMS members instead, or await placement refresh\n    ClusterMetadataService.instance.refreshCMSMembership();\n    throw new NotCMSException(\"Re-routed: this node is not a CMS member\");\n}\nClusterMetadataService.instance.commit(transform, onSuccess, onFailure);","handlingStrategy":"retry","validationCode":"CMSState state = ClusterMetadataService.instance.getState();\nif (state == CMSState.REMOTE)\n    throw new NotCMSException(\"Refusing to commit: this node is not a CMS member\");\nif (state == CMSState.GOSSIP)\n    throw new IllegalStateException(\"Node in gossip mode; cannot commit\");","typeGuard":"boolean canCommitLocally = () -> {\n    CMSState s = ClusterMetadataService.instance.getState();\n    return s == CMSState.LOCAL || s == CMSState.RESET;\n};","tryCatchPattern":"try\n{\n    commit(entryId, transform, lastKnown, retry);\n}\ncatch (NotCMSException e)\n{\n    // re-resolve current CMS members and retry the commit against them\n    ClusterMetadataService.instance.refreshCMSMembership();\n    retryAgainstCurrentCMS();\n}","preventionTips":["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)"],"tags":["tcm","cms","membership","commit","routing"],"backgroundTag":"not-cms-member","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}