{"record":{"id":"bb8d5baa87faaaaa","repo":"apache/cassandra","slug":"when-reinitializing-with-cluster-metadata-we-must","errorCode":null,"errorMessage":"When reinitializing with cluster metadata, we must be in the CMS","messagePattern":"When reinitializing with cluster metadata, we must be in the CMS","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/tcm/Startup.java","lineNumber":601,"sourceCode":"    public static void reinitializeWithClusterMetadata(String fileName, Function<Processor, Processor> wrapProcessor, Runnable initMessaging) throws IOException, StartupException\n    {\n        ClusterMetadata prev = ClusterMetadata.currentNullable();\n        // First set a minimal ClusterMetadata as some deserialization depends\n        // on ClusterMetadata.current() to access the partitioner\n        StubClusterMetadataService initial = StubClusterMetadataService.forClientTools();\n        ClusterMetadataService.unsetInstance();\n        StubClusterMetadataService.setInstance(initial);\n\n        ClusterMetadata metadata = ClusterMetadataService.deserializeClusterMetadata(fileName);\n        // if the partitioners are mismatching, we probably won't even get this far\n        if (metadata.partitioner != DatabaseDescriptor.getPartitioner())\n            throw new IllegalStateException(String.format(\"When reinitializing with cluster metadata, the same \" +\n                                                          \"partitioner must be used. Configured: %s, Serialized: %s\",\n                                                          DatabaseDescriptor.getPartitioner().getClass().getCanonicalName(),\n                                                          metadata.partitioner.getClass().getCanonicalName()));\n\n        if (!metadata.isCMSMember())\n            throw new IllegalStateException(\"When reinitializing with cluster metadata, we must be in the CMS\");\n\n        metadata = metadata.forceEpoch(metadata.epoch.nextEpoch());\n        ClusterMetadataService.unsetInstance();\n        LocalLog.LogSpec logSpec = LocalLog.logSpec()\n                                           .afterReplay(Startup::scrubDataDirectories,\n                                                        (_metadata) -> StorageService.instance.registerMBeans())\n                                           .withPreviousState(prev)\n                                           .withInitialState(metadata)\n                                           .withStorage(LogStorage.SystemKeyspace)\n                                           .withDefaultListeners()\n                                           .isReset(true);\n\n        ClusterMetadataService.setInstance(new ClusterMetadataService(new UniformRangePlacement(),\n                                                                      wrapProcessor,\n                                                                      ClusterMetadataService::state,\n                                                                      logSpec));\n\n        ClusterMetadataService.instance().log().ready();","sourceCodeStart":583,"sourceCodeEnd":619,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/Startup.java#L583-L619","documentation":"When reinitializing with a serialized ClusterMetadata snapshot, Startup.reinitializeWithClusterMetadata requires the local node to be a CMS member of that metadata (metadata.isCMSMember()). If the node is not part of the CMS in the snapshot, it throws IllegalStateException 'When reinitializing with cluster metadata, we must be in the CMS'. This reinitialization path is only valid for nodes that were CMS members; a non-CMS node cannot reinitialize from this snapshot.","triggerScenarios":"reinitializeWithClusterMetadata loads the serialized ClusterMetadata and metadata.isCMSMember() returns false — the node's id is not among the CMS members recorded in the snapshot; the snapshot came from a different node or the node was removed from CMS before the snapshot was taken.","commonSituations":"Restoring a metadata dump onto a node that was never (or no longer) a CMS member; snapshot taken before this node joined the CMS; operator using the reinitialize path intended only for CMS nodes during recovery.","solutions":["Confirm this node is (and was at snapshot time) a CMS member; the reinitialize-with-metadata path only applies to CMS nodes.","If this is a non-CMS node, use the normal discovery/startup path (initializeForDiscovery / initializeAsNonCmsNode) instead.","Take a fresh metadata snapshot from the correct (CMS-member) node if the current one is from the wrong source.","Rebuild this node as a regular member and, if needed, promote it to CMS afterwards with the CMS tooling."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before reinitializing, check this node is a CMS member of the snapshot\nif (!metadata.isCMSMember())\n    throw new ConfigurationException(\"Snapshot is not for a CMS-member node; use standard startup\");","typeGuard":null,"tryCatchPattern":"try { Startup.reinitializeWithClusterMetadata(fileName); }\ncatch (IllegalStateException e) {\n    if (\"When reinitializing with cluster metadata, we must be in the CMS\".equals(e.getMessage())) {\n        // fall back to normal discovery/startup path for non-CMS nodes\n    } else throw e;\n}","preventionTips":["Only use the reinitialize path on nodes confirmed as CMS members","Tag snapshots with the source node's id/role","Document recovery procedures per node role (CMS vs non-CMS)","Verify snapshot provenance before restore"],"tags":["tcm","cms","reinitialize","restore","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-14T11:17:12.474Z"}