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
- Install/restore the compressor library (and class) that the segment header names so createCompressor succeeds.
- Confirm the archive came from a stock Cassandra build; custom codecs are not portable across installations.
- Skip/exclude the affected segment from the restore and replay from another archive or accept the data loss for that segment.
- 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
- Avoid custom compression codecs on production commit logs
- Keep the compression library jars on the classpath of every restore target
- Verify archives replay on a test node before relying on them
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
- Cannot safely construct descriptor for segment, as name and…
- Cannot safely construct descriptor for segment, as name…
- Cannot safely construct descriptor for segment, either from…
- commitlog_disk_access_mode =
- Compression parameters too long, length
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)