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

  1. Remove or move out non-commit-log and unidentifiable files from the restore directory.
  2. Re-copy the affected segment from the archive; verify the copy is complete (compare sizes/checksums with the archived original).
  3. Check the file has a valid header: commit log segments written by Cassandra always begin with a descriptor header unless truncated.
  4. 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

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


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