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
- Upgrade Cassandra to a version whose CommitLogDescriptor.current_version is >= the segment's version before restoring the archive.
- Remove or exclude the newer-version segments from the restore archive directory.
- Verify the commitlog_archiving_properties restoreCommand/restoreDirectories point at archives from the same (or older) Cassandra version.
- 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
- Only restore archives from the same or older Cassandra version
- Label backup archives with the source Cassandra version
- Never mix commitlog directories across versions during downgrade
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
- Unable to list directory
- Cannot safely construct descriptor for segment, either from
- Cannot safely construct descriptor for segment, as name and
- Cannot safely construct descriptor for segment, as name desc
- Unknown compression
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/eca31221fbede985.
Report an issue: GitHub.