apache/cassandra · critical · java.io.IOException

Decompression failed due to

Error message

Decompression failed due to 

What it means

After decompressing, ZstdCompressorBase.uncompress checks Zstd.isError(dsz) on the returned size; if zstd reports an error code rather than a byte count, the frame was rejected and an IOException 'Decompression failed due to <zstd error name>' is thrown. The zstd error name (e.g. 'ZSTD_error_dstSize_tooSmall') identifies the specific failure.

Source

Thrown at src/java/org/apache/cassandra/io/compress/ZstdCompressorBase.java:123

     * @throws IOException
     */
    @Override
    public int uncompress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset)
    throws IOException
    {
        long dsz;
        try
        {
            dsz = Zstd.decompressByteArray(output, outputOffset, output.length - outputOffset,
                                           input, inputOffset, inputLength);
        }
        catch (Exception e)
        {
            throw new IOException("Decompression failed", e);
        }

        if (Zstd.isError(dsz))
            throw new IOException("Decompression failed due to " + Zstd.getErrorName(dsz));

        return (int) dsz;
    }

    /**
     * Decompress data via ByteBuffers
     *
     * @param input
     * @param output
     * @throws IOException
     */
    @Override
    public void uncompress(ByteBuffer input, ByteBuffer output) throws IOException
    {
        try
        {
            Zstd.decompress(output, input);
        } catch (Exception e)

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Read the zstd error name in the message; for dstSize_tooSmall, increase the output buffer to at least the stored decompressed chunk length.
  2. Verify the chunk_length_kb compression option matches the size used when the SSTable was written.
  3. Repair/replace corrupt data via `nodetool scrub`/`verify` and `nodetool repair` from replicas.

Example fix

// before: output buffer sized by wrong chunk length
byte[] out = new byte[oldChunkLen];
// after: use header-declared decompressed length
int decompressedLen = readChunkHeaderLength(input);
byte[] out = new byte[decompressedLen];
Defensive patterns

Strategy: try-catch

Try / catch

try {
    zstd.uncompress(input, inputOffset, inputLen, output, outputOffset);
} catch (IOException e) {
    if (e.getMessage().contains("dstSize_tooSmall")) {
        output = new byte[declaredDecompressedLength]; // retry with proper size
    } else throw e;
}

Prevention

When it happens

Trigger: Calling uncompress where Zstd.decompressByteArray returns an error code — most commonly when the output buffer is smaller than the actual decompressed size (dstSize_tooSmall), or the input frame is corrupt.

Common situations: Allocating output buffers from a chunk length that is too small for the data; corrupt SSTable chunks; mismatched chunk_length between writer and reader.

Related errors


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