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

  1. Do not call forceInitializedState() on an already-initialized cluster; use normal cluster join/log replay instead.
  2. Verify with metadata.epoch that the cluster is still at Epoch.FIRST before forcing initialization.
  3. 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.
  4. 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

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/d99441221195adb7. Report an issue: GitHub.