apache/cassandra · error · IllegalStateException
Cannot safely construct descriptor for segment, as name and
Error message
Cannot safely construct descriptor for segment, as name and header descriptors do not match (%s vs %s): %s
What it means
Thrown by maybeRestoreArchive() when a segment's filename-derived descriptor and its header-derived descriptor both exist but disagree (not equalIgnoringCompression). This means the file was renamed, tampered with, or its header corrupted — Cassandra cannot safely pick which identity is true and aborts the restore.
Source
Thrown at src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java:291
if (Strings.isNullOrEmpty(restoreDirectories))
return;
for (String dir : restoreDirectories.split(DELIMITER))
{
File[] files = new File(dir).tryList();
if (files == null)
{
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);View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Restore the file's original name matching its header descriptor (the error prints both descriptors), or re-copy the correctly named segment from the archive.
- Compare the two descriptors in the message (format/epoch/id) and re-fetch the correct file from backup.
- Verify archive integrity (checksums) to detect corrupted/overwritten segments.
- Never manually rename commit log segment files.
Example fix
# before (file renamed manually) CommitLog-4-0000000000000002.log (header says id 0000000000000005) # after (named to match header) mv CommitLog-4-0000000000000002.log CommitLog-4-0000000000000005.log
Defensive patterns
Strategy: validation
Validate before calling
for (File f : restoreDir.listFiles()) {
CommitLogDescriptor h = CommitLogDescriptor.fromHeader(f, DatabaseDescriptor.getEncryptionContext());
CommitLogDescriptor n = CommitLogDescriptor.isValid(f.getName()) ? CommitLogDescriptor.fromFileName(f.getName()) : null;
if (h != null && n != null && !h.equalsIgnoringCompression(n))
log.warn("Name/header descriptor mismatch, re-copy file: " + f);
} Try / catch
try { archiver.maybeRestoreArchive(); }
catch (IllegalStateException e) {
if (e.getMessage().contains("name and header descriptors do not match"))
log.error("Re-copy the segment under the name matching its header descriptor", e);
throw e;
} Prevention
- Never manually rename commit log segment files
- Checksum archived segments and re-verify after copy
- Investigate any file whose name and header disagree — likely corruption or overwrite
When it happens
Trigger: fromHeader != null && fromName != null && !fromHeader.equalsIgnoringCompression(fromName): e.g. a segment file was manually renamed to a different generation/id than recorded in its header.
Common situations: Operator renaming commit log files to 'fix' ordering; archived file overwritten by another segment's content; copying a segment under the wrong name; corruption of the first bytes of the file.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Unable to list directory
- Cannot safely construct descriptor for segment, either from
- Cannot safely construct descriptor for segment, as name desc
- Missing required directive CommitLogSync
- Batch sync specified, but commitlog_sync_period found.
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/916ad3a96787621e.
Report an issue: GitHub.