apache/cassandra · warning
Reverting to epoch
Error message
Reverting to epoch {} What it means
ClusterMetadataService.revertToEpoch logs a warning while forcibly rewinding cluster metadata to a prior epoch. It commits a ForceSnapshot built from the recovery log state at the given epoch, forcing the metadata forward with a new epoch. This is a destructive recovery operation and the warning flags that it is happening.
Solutions
- Verify the target epoch is correct before reverting; this discards later transformations.
- Take a metadata dump (`nodetool cms dump`) first for forensics.
- After revert, confirm all nodes converge to the forced epoch and CMS membership is intact.
- If you did not intend this, check what invoked revertToEpoch and halt the recovery script.
Defensive patterns
Strategy: try-catch
Validate before calling
// confirm target epoch is older than current and intended
if (!epoch.isBefore(ClusterMetadata.current().epoch)) throw new IllegalArgumentException("epoch not in the past"); Try / catch
try { cms.revertToEpoch(target); } catch (Throwable t) { logger.error("revert failed, cluster may be inconsistent", t); } Prevention
- Always dump metadata before reverting
- Only revert under a documented recovery procedure
- Verify cluster convergence after revert
When it happens
Trigger: An operator or internal recovery path calls revertToEpoch(epoch) to discard metadata changes after a given epoch — e.g. after detecting a bad transformation or corrupted state.
Common situations: Manual disaster recovery of the TCM log; rollback after a harmful topology change; recovery procedures guided by Cassandra documentation or support.
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
- Loading cluster metadata from
- All nodes are not yet upgraded
- Another sequence of kind
- Can not add a new in-progress sequence for
- Can not commit transformation
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/56f0fdc37f5e0289.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/tcm/ClusterMetadataService.java:561
return log.unsafeSetCommittedFromGossip(expected, updated);
}
public void setFromGossip(ClusterMetadata fromGossip)
{
logger.debug("Setting from gossip, new={}", fromGossip);
if (state() != GOSSIP)
throw new IllegalStateException("Can't apply a ClusterMetadata from gossip when CMSState is not GOSSIP: " + state());
log.unsafeSetCommittedFromGossip(fromGossip);
}
public void forceSnapshot(ClusterMetadata snapshot)
{
commit(new ForceSnapshot(snapshot));
}
public void revertToEpoch(Epoch epoch)
{
logger.warn("Reverting to epoch {}", epoch);
ClusterMetadata metadata = ClusterMetadata.current();
ClusterMetadata toApply = transformSnapshot(LogState.getForRecovery(epoch))
.forceEpoch(metadata.epoch.nextEpoch());
forceSnapshot(toApply);
}
/**
* dumps the cluster metadata at the given epoch, returns path to the generated file
* if the given Epoch is EMPTY, we dump the current metadata
*
* @param epoch dump clustermetadata at this epoch
* @param transformToEpoch transform the dumped metadata to this epoch
* @param version serialisation version
*/
public String dumpClusterMetadata(Epoch epoch, Epoch transformToEpoch, Version version) throws IOException
{
ClusterMetadata toDump = epoch.isAfter(Epoch.EMPTY)
? transformSnapshot(LogState.getForRecovery(epoch))View on GitHub (pinned to 88fd0f6a0e)