apache/cassandra · critical · IllegalStateException

Unknown compression

Error message

Unknown compression

What it means

When restoring an archived commit log segment, the descriptor read from its header can specify a compressor (e.g. LZ4, Snappy). CommitLogArchiver calls CompressionParams.createCompressor to instantiate it; if the class name cannot be resolved or configured, the ConfigurationException is wrapped in an IllegalStateException with message 'Unknown compression'. The segment cannot be replayed without the compressor.

Solutions

  1. Install/restore the compressor library (and class) that the segment header names so createCompressor succeeds.
  2. Confirm the archive came from a stock Cassandra build; custom codecs are not portable across installations.
  3. Skip/exclude the affected segment from the restore and replay from another archive or accept the data loss for that segment.
  4. Upgrade to a Cassandra version where the codec name used by the source cluster exists.

Example fix

// before: archive uses compressor 'Compressor7' not present on this node -> IllegalStateException('Unknown compression')
// after: restore original segment from a node using a supported codec, or add the codec's jar to the classpath before restart
Defensive patterns

Strategy: validation

Validate before calling

CommitLogDescriptor d = CommitLogDescriptor.fromFileName(segment.getName());
if (d != null && d.compression != null) {
    try { CompressionParams.createCompressor(d.compression); }
    catch (ConfigurationException e) { logger.error("Missing compressor {} for {}", d.compression, segment); }
}

Try / catch

try { archiver.maybeRestoreArchive(); } catch (IllegalStateException e) { logger.error("Cannot restore segment: {}", e.getMessage()); }

Prevention

When it happens

Trigger: maybeRestoreArchive reads a segment descriptor whose header carries a compression parameters string naming a compressor class that is not on the classpath or is misspelled/renamed, so CompressionParams.createCompressor throws ConfigurationException.

Common situations: Restoring archives written by a build with a custom/patched compression codec, classpath missing the codec library after an upgrade, or manually edited compression settings in the descriptor-carrying segment.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java:309

                    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 {}",
                                     fromFile.path(), toFile.path());
                    continue;
                }

                String command = FROM.matcher(restoreCommand).replaceAll(Matcher.quoteReplacement(fromFile.path()));
                command = TO.matcher(command).replaceAll(Matcher.quoteReplacement(toFile.path()));
                try
                {
                    exec(command);
                }

View on GitHub (pinned to 88fd0f6a0e)