apache/cassandra · error · IllegalStateException
Can only initialize cluster identifier during epoch %d, but
Error message
Can only initialize cluster identifier during epoch %d, but current epoch is %d
What it means
ClusterMetadata.forceInitializedState() may only set the cluster identifier while the metadata log is still at the very first epoch (Epoch.FIRST). Once any transformation has been committed, the epoch advances past FIRST and re-initializing the identifier would corrupt cluster identity, so an IllegalStateException is thrown.
Source
Thrown at src/java/org/apache/cassandra/tcm/ClusterMetadata.java:489
* @param addresses The NodeAddresses of the first CMS node.
* @param version Version info for the first CMS node.
* @param location The rack & DC of the first CMS node.
* @return ClusterMetadata instance in the correct state to constitute the base state of the INITIALIZE_CMS
* transformation
*/
public ClusterMetadata forceInitializedState(int clusterIdentifier,
NodeAddresses addresses,
NodeVersion version,
Location location)
{
if (this.metadataIdentifier != EMPTY_METADATA_IDENTIFIER)
throw new IllegalStateException(String.format("Can only initialize cluster identifier once, but it was already set to %d", this.metadataIdentifier));
if (clusterIdentifier == EMPTY_METADATA_IDENTIFIER)
throw new IllegalArgumentException("Can not initialize cluster with empty cluster identifier");
if (this.epoch.isAfter(Epoch.FIRST))
throw new IllegalStateException(String.format("Can only initialize cluster identifier during epoch %d, but current epoch is %d", Epoch.FIRST.getEpoch(), epoch.getEpoch()));
// Maybe register the first CMS node. If upgrading from gossip, this should be a no-op
Directory withRegistered = directory.with(addresses, location, version);
NodeId firstNode = withRegistered.peerId(addresses.broadcastAddress);
if (firstNode == null)
throw new IllegalStateException("Failed to find first CMS node in directory");
CMSMembership initialCMS = cmsMembership.startJoining(firstNode).finishJoining(firstNode);
return new ClusterMetadata(clusterIdentifier,
epoch,
partitioner,
schema,
withRegistered,
tokenMap,
placements,
accordFastPath,
lockedRanges,
inProgressSequences,View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Do not call forceInitializedState() on an already-initialized cluster; use normal cluster join/log replay instead.
- Verify with metadata.epoch that the cluster is still at Epoch.FIRST before forcing initialization.
- If this is a fresh cluster, ensure no other initialization path (or another node) committed entries first; if needed, start from a clean metadata log.
- If the identifier is already set, no action is needed — initialization already succeeded.
Example fix
// before
if (!metadata.epoch.isAfter(Epoch.FIRST))
ClusterMetadata.current().forceInitializedState(...);
// after
if (ClusterMetadata.current().epoch.equals(Epoch.FIRST))
cms.forceInitializedState(...);
else
logger.info("Cluster already initialized; skipping forced init"); Defensive patterns
Strategy: validation
Validate before calling
if (!ClusterMetadata.current().epoch.equals(Epoch.FIRST)) {
throw new IllegalStateException("Cluster already initialized past epoch 1; do not force init");
} Try / catch
try {
cms.forceInitializedState(...);
} catch (IllegalStateException e) {
logger.info("Cluster already initialized: {}", e.getMessage());
} Prevention
- Check the current epoch equals Epoch.FIRST before forcing initialization
- Only invoke forceInitializedState on a brand-new cluster
- Treat an already-set identifier as success, not an error
When it happens
Trigger: Calling forceInitializedState() when this.epoch.isAfter(Epoch.FIRST) — i.e. after the node has already applied metadata transformations and moved past epoch 1. Also thrown earlier if the identifier was already set.
Common situations: Bootstrapping a node against a cluster whose metadata log is already initialized (e.g. joining an existing cluster, or a restart racing with another node's initialization), or accidentally invoking forced initialization during a normal startup path.
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
- %s function resource has no function name
- Root-level resource can't have a parent
- ROOT data resource has no keyspace
- [%s] Writer already finished!
- Unknown endpoint %s
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/d99441221195adb7.
Report an issue: GitHub.