{"record":{"id":"340e7da12cb83f05","repo":"apache/cassandra","slug":"decompression-failed-due-to","errorCode":null,"errorMessage":"Decompression failed due to ","messagePattern":"Decompression failed due to ","errorType":"exception","errorClass":"java.io.IOException","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/io/compress/ZstdCompressorBase.java","lineNumber":123,"sourceCode":"     * @throws IOException\n     */\n    @Override\n    public int uncompress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset)\n    throws IOException\n    {\n        long dsz;\n        try\n        {\n            dsz = Zstd.decompressByteArray(output, outputOffset, output.length - outputOffset,\n                                           input, inputOffset, inputLength);\n        }\n        catch (Exception e)\n        {\n            throw new IOException(\"Decompression failed\", e);\n        }\n\n        if (Zstd.isError(dsz))\n            throw new IOException(\"Decompression failed due to \" + Zstd.getErrorName(dsz));\n\n        return (int) dsz;\n    }\n\n    /**\n     * Decompress data via ByteBuffers\n     *\n     * @param input\n     * @param output\n     * @throws IOException\n     */\n    @Override\n    public void uncompress(ByteBuffer input, ByteBuffer output) throws IOException\n    {\n        try\n        {\n            Zstd.decompress(output, input);\n        } catch (Exception e)","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/compress/ZstdCompressorBase.java#L105-L141","documentation":"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.","triggerScenarios":"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.","commonSituations":"Allocating output buffers from a chunk length that is too small for the data; corrupt SSTable chunks; mismatched chunk_length between writer and reader.","solutions":["Read the zstd error name in the message; for dstSize_tooSmall, increase the output buffer to at least the stored decompressed chunk length.","Verify the chunk_length_kb compression option matches the size used when the SSTable was written.","Repair/replace corrupt data via `nodetool scrub`/`verify` and `nodetool repair` from replicas."],"exampleFix":"// before: output buffer sized by wrong chunk length\nbyte[] out = new byte[oldChunkLen];\n// after: use header-declared decompressed length\nint decompressedLen = readChunkHeaderLength(input);\nbyte[] out = new byte[decompressedLen];","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    zstd.uncompress(input, inputOffset, inputLen, output, outputOffset);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"dstSize_tooSmall\")) {\n        output = new byte[declaredDecompressedLength]; // retry with proper size\n    } else throw e;\n}","preventionTips":["Size output buffers from the chunk header's decompressed length, never a hardcoded constant.","Match chunk_length_kb between writer and reader.","Monitor for this message as an early corruption signal."],"tags":["zstd","decompression","buffer-size","data-corruption"],"backgroundTag":"decompression-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}