apache/cassandra · warning

Previous epoch indicates that the has not been initialized…

Error message

Previous epoch {} indicates that the {} has not been initialized yet, not committing entry {}/{} at epoch {}

What it means

A warn log in DistributedMetadataLogKeyspace.tryCommit when the previously observed epoch in the metadata log precedes the FIRST epoch, meaning the log was never initialized. The commit is skipped (returns false) because committing an entry to an uninitialized log would be invalid.

Solutions

  1. Ensure the metadata log is initialized (restart node so insertPreInitialize runs successfully and confirm CAS succeeds)
  2. Check system_metadata_log contents; if empty/corrupted on a live cluster, rebuild metadata log state per support guidance
  3. Investigate ordering: initialization must complete before any tryCommit; look for failed init logs (e.g. 'Timed out while trying to CAS' / 'Could not initialize log')
  4. If restore-related, follow the documented snapshot/restore procedure so the metadata log is restored consistently
Defensive patterns

Strategy: validation

Validate before calling

// guard before committing
Epoch prev = currentLogEpoch();
if (prev.isBefore(Epoch.FIRST)) {
    throw new IllegalStateException("Metadata log not initialized; cannot commit " + entryId);
}

Type guard

boolean logInitialized(Epoch previousEpoch) { return !previousEpoch.isBefore(Epoch.FIRST); }

Try / catch

try { boolean ok = tryCommit(...); if (!ok) retryAfterInit(); }
catch (CasWriteTimeoutException e) { scheduleRetry(); }

Prevention

When it happens

Trigger: tryCommit is invoked with a previousEpoch before FIRST — the log table is empty/not initialized but a metadata transformation commit is attempted.

Common situations: Broken or partially-initialized system_metadata_log table (e.g. restored from backup, truncated manually); a race where commit runs before initialization completes; corrupted metadata state after failed bootstrap.

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/9eb5a61c223367e9. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/schema/DistributedMetadataLogKeyspace.java:131

        catch (Throwable t)
        {
            JVMStabilityInspector.inspectThrowable(t);
            logger.error("Caught an exception while trying to CAS", t);
            return false;
        }
    }

    public static boolean tryCommit(Entry.Id entryId,
                                    Transformation transform,
                                    Epoch previousEpoch,
                                    Epoch nextEpoch)
    {
        try
        {
            // log is not initialized yet this is unexpected
            if (previousEpoch.isBefore(FIRST))
            {
                logger.warn("Previous epoch {} indicates that the {} has not been initialized yet, " +
                            "not committing entry {}/{} at epoch {}",
                            previousEpoch, METADATA_KEYSPACE_NAME, entryId, transform, nextEpoch);
                return false;
            }

            ByteBuffer serializedTransform = transform.kind().toVersionedBytes(transform);
            String query = String.format("INSERT INTO %s.%s (epoch, entry_id, transformation, kind) " +
                                         "VALUES (?, ?, ?, ?) " +
                                         "IF NOT EXISTS;",
                                         METADATA_KEYSPACE_NAME, TABLE_NAME);
            UntypedResultSet result = QueryProcessor.execute(query,
                                                             ConsistencyLevel.QUORUM,
                                                             nextEpoch.getEpoch(),
                                                             entryId.entryId,
                                                             serializedTransform,
                                                             transform.kind().id);

            return result.one().getBoolean("[applied]");

View on GitHub (pinned to 88fd0f6a0e)