apache/cassandra · error · IllegalStateException
Migration already initiated by
Error message
Migration already initiated by
What it means
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.
Source
Thrown at src/java/org/apache/cassandra/tcm/migration/Election.java:100
}
private Election(MessageDelivery messaging)
{
this.messaging = messaging;
this.prepareHandler = new PrepareHandler();
this.abortHandler = new AbortHandler();
}
public void nominateSelf(Set<InetAddressAndPort> candidates, Set<InetAddressAndPort> ignoredEndpoints, ClusterMetadata metadata, boolean verifyAllPeersMetadata)
{
// Note: this is probably identical to the supplied metadata, but not guaranteed to be
ClusterMetadata priorState = ClusterMetadata.current();
Set<InetAddressAndPort> sendTo = new HashSet<>(candidates);
sendTo.removeAll(ignoredEndpoints);
sendTo.remove(FBUtilities.getBroadcastAddressAndPort());
CMSInitializationRequest initializationRequest = new CMSInitializationRequest(FBUtilities.getBroadcastAddressAndPort(), UUID.randomUUID(), metadata);
if (!updateInitiator(null, initializationRequest.initiator))
throw new IllegalStateException("Migration already initiated by " + initiator.get());
try
{
initiate(initializationRequest, sendTo, metadata, verifyAllPeersMetadata);
finish(sendTo);
}
catch (Throwable e)
{
logger.error("Got error nominating self", e);
abort(initializationRequest.initiator, sendTo);
ClusterMetadata currentState = ClusterMetadata.current();
// Clean up the system_cluster_metadata keyspace which may have been created by PRE_INITIALIZE_CMS
Keyspace metaKeyspace = currentState.schema.getKeyspace(SchemaConstants.METADATA_KEYSPACE_NAME);
if (metaKeyspace != null)
metaKeyspace.unload(true);
// Remove entries from system_schema tables
Keyspaces.KeyspacesDiff diff = Keyspaces.diff(currentState.schema.getKeyspaces(), priorState.schema.getKeyspaces());View on GitHub (pinned to 88fd0f6a0e)
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
Example fix
// before // node A and node B both run: election.nominateSelf(...) -> one throws // after // ensure only one initiator: if (Election.initiator().isEmpty()) election.nominateSelf(...);
Defensive patterns
Strategy: try-catch
Validate before calling
if (Election.initiator().isPresent()) throw new IllegalStateException("Migration already in progress by " + Election.initiator().get()); Try / catch
try { election.nominateSelf(candidates, ignored, metadata, verify); } catch (IllegalStateException e) { logger.warn("Another initiator started migration: {}", e.getMessage()); } Prevention
- 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
When it happens
Trigger: Calling nominateSelf (e.g. via nodetool cms initiate/self-nomination) while Election.initiator already holds a value from a prior or concurrent migration attempt.
Common situations: Two operators running the migration command simultaneously; retrying a failed migration whose initiator field was never cleared; a crashed node leaving stale initiator state.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Got duplicate initiate migration message from %s, migration
- Unknown endpoint %s
- Can only initialize cluster identifier during epoch %d, but
- Failed to find first CMS node in directory
- Core cluster metadata objects should be addressed directly,
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/3d4efa8a4ee8c665.
Report an issue: GitHub.