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;
        }

        try

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Check the cause exception via getCause() to see the exact Zstd failure
  2. Verify the input chunk belongs to the file whose compression metadata (dictionary) is being used
  3. Confirm the dictionary used at read time matches the one recorded in the sstable compression parameters
  4. 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

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


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