apache/cassandra · error · java.io.IOException
Decompression failed
Error message
Decompression failed
What it means
Thrown by ZstdDictionaryCompressor.uncompress when the underlying Zstd JNI decompression call (Zstd.decompressFastDict) throws an exception, e.g. due to corrupted, truncated, or non-Zstd input, or a mismatched/incompatible decompression dictionary. It wraps the original exception as the cause of an IOException so callers of the compression layer can handle it uniformly.
Source
Thrown at src/java/org/apache/cassandra/io/compress/ZstdDictionaryCompressor.java:157
@Override
public int uncompress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) throws IOException
{
// fallback to non-dict zstd compressor
if (dictionary == null)
{
return super.uncompress(input, inputOffset, inputLength, output, outputOffset);
}
int dsz;
try
{
dsz = (int) Zstd.decompressFastDict(output, outputOffset,
input, inputOffset, inputLength,
dictionary.dictionaryForDecompression());
}
catch (Exception e)
{
throw new IOException("Decompression failed", e);
}
if (Zstd.isError(dsz))
throw new IOException("Decompression failed due to " + Zstd.getErrorName(dsz));
return dsz;
}
@Override
public void uncompress(ByteBuffer input, ByteBuffer output) throws IOException
{
if (dictionary == null)
{
super.uncompress(input, output);
return;
}
tryView on GitHub (pinned to 88fd0f6a0e)
Solutions
- Check the cause exception via getCause() to see the exact Zstd failure
- Verify the input chunk belongs to the file whose compression metadata (dictionary) is being used
- Confirm the dictionary used at read time matches the one recorded in the sstable compression parameters
- Re-read or re-fetch the corrupted data from a replica/backup
Example fix
// before
byte[] out = new byte[1024];
compressor.uncompress(chunk, out, 0);
// after
try {
compressor.uncompress(chunk, out, 0);
} catch (IOException e) {
logger.error("Zstd decompression failed for chunk, cause: {}", e.getCause());
throw new CorruptSSTableException(e, file.getPath());
} Defensive patterns
Strategy: try-catch
Validate before calling
if (input == null || inputLength <= 0) throw new IllegalArgumentException("invalid compressed input"); Type guard
boolean looksCompressed(byte[] in) { return in != null && in.length >= 4; } Try / catch
try { compressor.uncompress(input, output, outputOffset); } catch (IOException e) { throw new CorruptSSTableException(e.getCause(), chunkPath); } Prevention
- Always use the dictionary from the same sstable compression parameters the data was written with
- Validate chunk lengths against file metadata before decompressing
- Handle CorruptSSTableException by re-fetching the data from a replica
- Log e.getCause() to capture the underlying Zstd error
When it happens
Trigger: Calling uncompress(byte[], byte[], int) (directly or via decompressedLength) with input bytes that were not produced by this compressor, are truncated, or were compressed with a different (or no) dictionary, causing the Zstd JNI call to throw.
Common situations: Reading an sstable compressed with Zstd+dictionary after the dictionary was rotated or lost; manually assembling compressed chunks; version mismatch between writer and reader compression parameters.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Decompression failed
- Decompression failed due to
- Decompressed lengths mismatch
- Decompression failed due to
- Compression failed
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/4b8f835eb308e11a.
Report an issue: GitHub.