apache/cassandra · critical · IllegalStateException

Unsupported commit log version:

Error message

Unsupported commit log version: 

What it means

During commit log archive restore (CommitLogArchiver.maybeRestoreArchive), a descriptor is built for each archived segment from its header or file name. If the resulting descriptor's version is greater than CommitLogDescriptor.current_version, the node cannot safely read the segment, so an IllegalStateException is thrown. This guards against restoring commit logs written by a newer Cassandra version.

Source

Thrown at src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java:299

                throw new RuntimeException("Unable to list directory " + dir);
            }
            for (File fromFile : files)
            {
                CommitLogDescriptor fromHeader = CommitLogDescriptor.fromHeader(fromFile, DatabaseDescriptor.getEncryptionContext());
                CommitLogDescriptor fromName = CommitLogDescriptor.isValid(fromFile.name()) ? CommitLogDescriptor.fromFileName(fromFile.name()) : null;
                CommitLogDescriptor descriptor;
                if (fromHeader == null && fromName == null)
                    throw new IllegalStateException("Cannot safely construct descriptor for segment, either from its name or its header: " + fromFile.path());
                else if (fromHeader != null && fromName != null && !fromHeader.equalsIgnoringCompression(fromName))
                    throw new IllegalStateException(String.format("Cannot safely construct descriptor for segment, as name and header descriptors do not match (%s vs %s): %s", fromHeader, fromName, fromFile.path()));
                else if (fromName != null && fromHeader == null)
                    throw new IllegalStateException("Cannot safely construct descriptor for segment, as name descriptor implies a version that should contain a header descriptor, but that descriptor could not be read: " + fromFile.path());
                else if (fromHeader != null)
                    descriptor = fromHeader;
                else descriptor = fromName;

                if (descriptor.version > CommitLogDescriptor.current_version)
                    throw new IllegalStateException("Unsupported commit log version: " + descriptor.version);

                if (descriptor.compression != null)
                {
                    try
                    {
                        CompressionParams.createCompressor(descriptor.compression);
                    }
                    catch (ConfigurationException e)
                    {
                        throw new IllegalStateException("Unknown compression", e);
                    }
                }

                File toFile = new File(DatabaseDescriptor.getCommitLogLocation(), descriptor.fileName());
                if (toFile.exists())
                {
                    if (logger.isTraceEnabled())
                        logger.trace("Skipping restore of archive {} as the segment already exists in the restore location {}",

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Upgrade Cassandra to a version whose CommitLogDescriptor.current_version is >= the segment's version before restoring the archive.
  2. Remove or exclude the newer-version segments from the restore archive directory.
  3. Verify the commitlog_archiving_properties restoreCommand/restoreDirectories point at archives from the same (or older) Cassandra version.
  4. If downgrade is intentional, let the node start without replaying old archives and rely on backups/snapshots instead.

Example fix

// before: restoring 5.0 segments into a 4.0 node -> IllegalStateException
// after: run the target (newer) Cassandra version or filter the archive
assert descriptor.version <= CommitLogDescriptor.current_version : "restore archive must come from same or older Cassandra version";
Defensive patterns

Strategy: validation

Validate before calling

CommitLogDescriptor d = CommitLogDescriptor.fromFileName(segment.getName());
if (d != null && d.version > CommitLogDescriptor.current_version)
    throw new IllegalStateException("Segment " + segment + " written by newer Cassandra; upgrade before restore");

Try / catch

try { archiver.maybeRestoreArchive(); } catch (IllegalStateException e) { logger.error("Restore aborted: {}", e.getMessage()); /* skip archive or upgrade */ }

Prevention

When it happens

Trigger: Calling maybeRestoreArchive (triggered at node startup when commitlog_archiving.properties has restore directives) and an archived segment's descriptor.version exceeds CommitLogDescriptor.current_version — i.e. the segment was written by a newer Cassandra release than the running one.

Common situations: Downgrading a Cassandra node, restoring archived commit logs taken on a newer cluster (e.g. 5.0 segments into a 4.0 node), or pointing restore_command at a backup directory containing segments from a different major version.

Related errors


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