apache/cassandra · error · IllegalStateException
Cannot safely construct descriptor for segment, either from
Error message
Cannot safely construct descriptor for segment, either from its name or its header:
What it means
Thrown by maybeRestoreArchive() when an archived commit log segment can neither be identified from its filename nor from its binary header (both CommitLogDescriptor.fromHeader and fromFileName return null). Cassandra refuses to guess and aborts the restore rather than replaying an unidentified segment.
Source
Thrown at src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java:289
public void maybeRestoreArchive()
{
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)View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Remove or move out non-commit-log and unidentifiable files from the restore directory.
- Re-copy the affected segment from the archive; verify the copy is complete (compare sizes/checksums with the archived original).
- Check the file has a valid header: commit log segments written by Cassandra always begin with a descriptor header unless truncated.
- Confirm the file name matches CommitLog-<version>-<id>.log pattern.
Example fix
# before (restore dir contains a stray file) /mnt/restore/notes.txt # after mv /mnt/restore/notes.txt /tmp/ && ls /mnt/restore # only CommitLog-*.log segment files remain
Defensive patterns
Strategy: validation
Validate before calling
for (File f : restoreDir.listFiles()) {
boolean nameOk = CommitLogDescriptor.isValid(f.getName());
boolean headerOk = CommitLogDescriptor.fromHeader(f, DatabaseDescriptor.getEncryptionContext()) != null;
if (!nameOk && !headerOk)
log.warn("Unidentifiable file in restore dir, remove it: " + f);
} Try / catch
try { archiver.maybeRestoreArchive(); }
catch (IllegalStateException e) {
if (e.getMessage().startsWith("Cannot safely construct descriptor"))
log.error("Remove/re-copy unidentifiable segment files in restore dirs", e);
throw e;
} Prevention
- Only copy commit log segment files into restore directories
- Verify completed copies with checksums before starting the node
- Clean out stale/foreign files from restore directories before each restore
When it happens
Trigger: A file in a restore directory is not a recognizable commit log segment: corrupted header, truncated file (header not yet written), foreign/random file placed in the restore dir, or a filename not matching the CommitLogSegment pattern.
Common situations: Manually copying stray files (e.g. backup notes, partial uploads) into the restore directory; interrupted archive copy leaving a 0-byte segment; incompatible/foreign segment files from another storage engine.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Cannot safely construct descriptor for segment, as name desc
- Unable to list directory
- Cannot safely construct descriptor for segment, as name and
- 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/c5128228ef376e4f.
Report an issue: GitHub.