{"record":{"id":"86dc85a568d88f0e","repo":"apache/cassandra","slug":"can-t-apply-a-clustermetadata-from-gossip-when-cms","errorCode":null,"errorMessage":"Can't apply a ClusterMetadata from gossip when CMSState is not GOSSIP: ","messagePattern":"Can't apply a ClusterMetadata from gossip when CMSState is not GOSSIP: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tcm/ClusterMetadataService.java","lineNumber":541,"sourceCode":"\n        try\n        {\n            reconfigureCMS(ReplicationParams.meta(metadata));\n        }\n        catch (Throwable t)\n        {\n            JVMStabilityInspector.inspectThrowable(t);\n            logger.warn(\"Could not reconfigure CMS, operator should run `nodetool cms reconfigure` to make sure CMS placement is correct\", t);\n        }\n    }\n\n    public boolean applyFromGossip(ClusterMetadata expected, ClusterMetadata updated)\n    {\n        logger.debug(\"Applying from gossip, current={} new={}\", expected, updated);\n        if (!expected.epoch.isBefore(Epoch.EMPTY))\n            throw new IllegalStateException(\"Can't apply a ClusterMetadata from gossip with epoch \" + expected.epoch);\n        if (state() != GOSSIP)\n            throw new IllegalStateException(\"Can't apply a ClusterMetadata from gossip when CMSState is not GOSSIP: \" + state());\n\n        return log.unsafeSetCommittedFromGossip(expected, updated);\n    }\n\n    public void setFromGossip(ClusterMetadata fromGossip)\n    {\n        logger.debug(\"Setting from gossip, new={}\", fromGossip);\n        if (state() != GOSSIP)\n            throw new IllegalStateException(\"Can't apply a ClusterMetadata from gossip when CMSState is not GOSSIP: \" + state());\n        log.unsafeSetCommittedFromGossip(fromGossip);\n    }\n\n    public void forceSnapshot(ClusterMetadata snapshot)\n    {\n        commit(new ForceSnapshot(snapshot));\n    }\n\n    public void revertToEpoch(Epoch epoch)","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/ClusterMetadataService.java#L523-L559","documentation":"applyFromGossip requires the ClusterMetadataService to be in the GOSSIP state (the pre-migration mode). If the service has already transitioned to TCM/CMS state, applying metadata from gossip is rejected with IllegalStateException including the current state, since gossip is no longer the authoritative source.","triggerScenarios":"Calling applyFromGossip(expected, updated) when ClusterMetadataService.state() != CMSState.GOSSIP — e.g. after the node completed the gossip-to-TCM migration and its state moved to TCM/ELECTION.","commonSituations":"Gossip messages still arriving after migration completed; mixed-version cluster where an old node pushes metadata to a migrated node; calling internal migration APIs out of order during testing or custom tooling.","solutions":["Check ClusterMetadataService.instance().state() == GOSSIP before calling applyFromGossip.","Complete the cluster migration so gossip peers stop sending metadata updates to migrated nodes.","If this happens during a rolling upgrade, ensure all nodes migrate in the documented order and drop stale gossip traffic.","In test tooling, reset the CMS state to GOSSIP before invoking gossip-apply paths."],"exampleFix":"// before\nservice.applyFromGossip(expected, updated);\n// after\nif (ClusterMetadataService.instance().state() == CMSState.GOSSIP)\n    service.applyFromGossip(expected, updated);\nelse\n    logger.warn(\"Ignoring gossip metadata while state is {}\", ClusterMetadataService.instance().state());","handlingStrategy":"validation","validationCode":"if (ClusterMetadataService.instance().state() != CMSState.GOSSIP) return false;","typeGuard":"boolean canApplyFromGossip = ClusterMetadataService.instance().state() == CMSState.GOSSIP;","tryCatchPattern":"try { service.applyFromGossip(expected, updated); } catch (IllegalStateException e) { logger.warn(\"Cannot apply from gossip in state {}: {}\", ClusterMetadataService.instance().state(), e.getMessage()); }","preventionTips":["Check service state before any gossip-apply call","Ensure all peers finish migration to stop stale gossip pushes","Upgrade all nodes promptly during rolling upgrades"],"tags":["cluster-metadata","gossip-migration","service-state","precondition"],"backgroundTag":"invalid-state-transition","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"}