{"record":{"id":"3d4efa8a4ee8c665","repo":"apache/cassandra","slug":"migration-already-initiated-by","errorCode":null,"errorMessage":"Migration already initiated by ","messagePattern":"Migration already initiated by ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tcm/migration/Election.java","lineNumber":100,"sourceCode":"    }\n\n    private Election(MessageDelivery messaging)\n    {\n        this.messaging = messaging;\n        this.prepareHandler = new PrepareHandler();\n        this.abortHandler = new AbortHandler();\n    }\n\n    public void nominateSelf(Set<InetAddressAndPort> candidates, Set<InetAddressAndPort> ignoredEndpoints, ClusterMetadata metadata, boolean verifyAllPeersMetadata)\n    {\n        // Note: this is probably identical to the supplied metadata, but not guaranteed to be\n        ClusterMetadata priorState = ClusterMetadata.current();\n        Set<InetAddressAndPort> sendTo = new HashSet<>(candidates);\n        sendTo.removeAll(ignoredEndpoints);\n        sendTo.remove(FBUtilities.getBroadcastAddressAndPort());\n        CMSInitializationRequest initializationRequest = new CMSInitializationRequest(FBUtilities.getBroadcastAddressAndPort(), UUID.randomUUID(), metadata);\n        if (!updateInitiator(null, initializationRequest.initiator))\n            throw new IllegalStateException(\"Migration already initiated by \" + initiator.get());\n        try\n        {\n            initiate(initializationRequest, sendTo, metadata, verifyAllPeersMetadata);\n            finish(sendTo);\n        }\n        catch (Throwable e)\n        {\n            logger.error(\"Got error nominating self\", e);\n            abort(initializationRequest.initiator, sendTo);\n            ClusterMetadata currentState = ClusterMetadata.current();\n\n            // Clean up the system_cluster_metadata keyspace which may have been created by PRE_INITIALIZE_CMS\n            Keyspace metaKeyspace = currentState.schema.getKeyspace(SchemaConstants.METADATA_KEYSPACE_NAME);\n            if (metaKeyspace != null)\n                metaKeyspace.unload(true);\n\n            // Remove entries from system_schema tables\n            Keyspaces.KeyspacesDiff diff = Keyspaces.diff(currentState.schema.getKeyspaces(), priorState.schema.getKeyspaces());","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/migration/Election.java#L82-L118","documentation":"Election.nominateSelf initiates the CMS migration protocol. Before starting, it calls updateInitiator(null, initiator) which only succeeds when no migration initiator is already recorded. If another node (or a previous run of this node) already initiated migration, an IllegalStateException naming the existing initiator is thrown.","triggerScenarios":"Calling nominateSelf (e.g. via nodetool cms initiate/self-nomination) while Election.initiator already holds a value from a prior or concurrent migration attempt.","commonSituations":"Two operators running the migration command simultaneously; retrying a failed migration whose initiator field was never cleared; a crashed node leaving stale initiator state.","solutions":["Check the current initiator first (e.g. via nodetool cms or logs) and let the existing initiator finish","If the recorded initiator node is dead, run Election/abortInitialization on that node with the expected initiator to reset state","Wait for the in-flight migration to complete (state MIGRATED) before initiating again","As a last resort, clear stale initiator state by re-running initialization with the correct --ignore list"],"exampleFix":"// before\n// node A and node B both run: election.nominateSelf(...)  -> one throws\n// after\n// ensure only one initiator:\nif (Election.initiator().isEmpty()) election.nominateSelf(...);","handlingStrategy":"try-catch","validationCode":"if (Election.initiator().isPresent()) throw new IllegalStateException(\"Migration already in progress by \" + Election.initiator().get());","typeGuard":null,"tryCatchPattern":"try { election.nominateSelf(candidates, ignored, metadata, verify); } catch (IllegalStateException e) { logger.warn(\"Another initiator started migration: {}\", e.getMessage()); }","preventionTips":["Only run the CMS migration command from a single operator/coordinator","Check current initiator state before nominating","Coordinate retries so a failed attempt's initiator state is cleared first"],"tags":["cassandra","tcm","concurrency"],"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-14T16:17:12.679Z"}