{"record":{"id":"9eba85fe2b978df4","repo":"apache/cassandra","slug":"cluster-metadata-is-already-initialized-to-s","errorCode":null,"errorMessage":"Cluster metadata is already initialized to %s.","messagePattern":"Cluster metadata is already initialized to (.+?)\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tcm/ClusterMetadataService.java","lineNumber":117,"sourceCode":"import static org.apache.cassandra.tcm.ClusterMetadataService.State.GOSSIP;\nimport static org.apache.cassandra.tcm.ClusterMetadataService.State.LOCAL;\nimport static org.apache.cassandra.tcm.ClusterMetadataService.State.REMOTE;\nimport static org.apache.cassandra.tcm.ClusterMetadataService.State.RESET;\nimport static org.apache.cassandra.tcm.compatibility.GossipHelper.emptyWithSchemaFromSystemTables;\nimport static org.apache.cassandra.utils.Clock.Global.nanoTime;\nimport static org.apache.cassandra.utils.Collectors3.toImmutableSet;\n\npublic class ClusterMetadataService\n{\n    private static final Logger logger = LoggerFactory.getLogger(ClusterMetadataService.class);\n\n    private static ClusterMetadataService instance;\n    private static Throwable trace;\n\n    public static void setInstance(ClusterMetadataService newInstance)\n    {\n        if (instance != null)\n            throw new IllegalStateException(String.format(\"Cluster metadata is already initialized to %s.\", instance),\n                                            trace);\n        instance = newInstance;\n        RegistrationStatus.instance.onInitialized();\n        if (newInstance.metadata().myNodeId() != NodeId.UNREGISTERED)\n            RegistrationStatus.instance.onRegistration();\n        trace = new RuntimeException(\"Previously initialized trace\");\n        DatabaseDescriptor.applyLocator();\n    }\n\n    @VisibleForTesting\n    public static ClusterMetadataService unsetInstance()\n    {\n        ClusterMetadataService tmp = instance();\n        RegistrationStatus.instance.resetState();\n        instance = null;\n        return tmp;\n    }\n","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/ClusterMetadataService.java#L99-L135","documentation":"ClusterMetadataService is a process-wide singleton. setInstance() throws IllegalStateException (with a 'Previously initialized trace' attached as cause on the first call path) if it is called when a CMS instance has already been installed, to prevent silently swapping cluster metadata backends at runtime.","triggerScenarios":"Calling ClusterMetadataService.setInstance(newCms) more than once in the same JVM — e.g. tests initializing multiple clusters, or a node re-running initialization after startup.","commonSituations":"In-JVM dtest frameworks creating several clusters without resetting the singleton, or code paths that re-invoke startup/initialization logic on restart within the same process.","solutions":["Call setInstance() only once per JVM; guard initialization with a check of ClusterMetadataService.instance.","In tests, use the framework's cluster-per-JVM or classloader isolation mechanisms.","If re-initialization is intended, restructure to a fresh process/classloader rather than reassigning the singleton."],"exampleFix":"// before\nClusterMetadataService.setInstance(newCms); // second call -> IllegalStateException\n// after\nif (ClusterMetadataService.instance() == null)\n    ClusterMetadataService.setInstance(newCms);","handlingStrategy":"validation","validationCode":"if (ClusterMetadataService.instance() != null) {\n    logger.info(\"CMS already initialized; skipping setInstance\");\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    ClusterMetadataService.setInstance(newCms);\n} catch (IllegalStateException e) {\n    logger.warn(\"CMS already set; keeping existing instance\", e);\n}","preventionTips":["Initialize CMS exactly once per JVM","Use classloader/process isolation for multi-cluster test setups","Check instance nullity before calling setInstance"],"tags":["cassandra","tcm","singleton","initialization"],"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"}