{"record":{"id":"916ad3a96787621e","repo":"apache/cassandra","slug":"cannot-safely-construct-descriptor-for-segment-as","errorCode":null,"errorMessage":"Cannot safely construct descriptor for segment, as name and header descriptors do not match (%s vs %s): %s","messagePattern":"Cannot safely construct descriptor for segment, as name and header descriptors do not match \\((.+?) vs (.+?)\\): (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java","lineNumber":291,"sourceCode":"        if (Strings.isNullOrEmpty(restoreDirectories))\n            return;\n\n        for (String dir : restoreDirectories.split(DELIMITER))\n        {\n            File[] files = new File(dir).tryList();\n            if (files == null)\n            {\n                throw new RuntimeException(\"Unable to list directory \" + dir);\n            }\n            for (File fromFile : files)\n            {\n                CommitLogDescriptor fromHeader = CommitLogDescriptor.fromHeader(fromFile, DatabaseDescriptor.getEncryptionContext());\n                CommitLogDescriptor fromName = CommitLogDescriptor.isValid(fromFile.name()) ? CommitLogDescriptor.fromFileName(fromFile.name()) : null;\n                CommitLogDescriptor descriptor;\n                if (fromHeader == null && fromName == null)\n                    throw new IllegalStateException(\"Cannot safely construct descriptor for segment, either from its name or its header: \" + fromFile.path());\n                else if (fromHeader != null && fromName != null && !fromHeader.equalsIgnoringCompression(fromName))\n                    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()));\n                else if (fromName != null && fromHeader == null)\n                    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());\n                else if (fromHeader != null)\n                    descriptor = fromHeader;\n                else descriptor = fromName;\n\n                if (descriptor.version > CommitLogDescriptor.current_version)\n                    throw new IllegalStateException(\"Unsupported commit log version: \" + descriptor.version);\n\n                if (descriptor.compression != null)\n                {\n                    try\n                    {\n                        CompressionParams.createCompressor(descriptor.compression);\n                    }\n                    catch (ConfigurationException e)\n                    {\n                        throw new IllegalStateException(\"Unknown compression\", e);","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java#L273-L309","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before (file renamed manually)\nCommitLog-4-0000000000000002.log  (header says id 0000000000000005)\n# after (named to match header)\nmv CommitLog-4-0000000000000002.log CommitLog-4-0000000000000005.log","handlingStrategy":"validation","validationCode":"for (File f : restoreDir.listFiles()) {\n    CommitLogDescriptor h = CommitLogDescriptor.fromHeader(f, DatabaseDescriptor.getEncryptionContext());\n    CommitLogDescriptor n = CommitLogDescriptor.isValid(f.getName()) ? CommitLogDescriptor.fromFileName(f.getName()) : null;\n    if (h != null && n != null && !h.equalsIgnoringCompression(n))\n        log.warn(\"Name/header descriptor mismatch, re-copy file: \" + f);\n}","typeGuard":null,"tryCatchPattern":"try { archiver.maybeRestoreArchive(); }\ncatch (IllegalStateException e) {\n    if (e.getMessage().contains(\"name and header descriptors do not match\"))\n        log.error(\"Re-copy the segment under the name matching its header descriptor\", e);\n    throw e;\n}","preventionTips":["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"],"tags":["cassandra","commitlog","restore","integrity"],"backgroundTag":"checksum-mismatch","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}