{"record":{"id":"48b06bfe8f116b8a","repo":"apache/cassandra","slug":"decompression-failed","errorCode":null,"errorMessage":"Decompression failed","messagePattern":"Decompression failed","errorType":"exception","errorClass":"java.io.IOException","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/io/compress/ZstdCompressorBase.java","lineNumber":119,"sourceCode":"     * @param inputLength\n     * @param output\n     * @param outputOffset\n     * @return\n     * @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    {","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/compress/ZstdCompressorBase.java#L101-L137","documentation":"ZstdCompressorBase.uncompress(byte[], ...) wraps any exception thrown by the zstd-jni Zstd.decompressByteArray call in an IOException with the message 'Decompression failed', preserving the cause. This indicates zstd itself rejected the frame (malformed data, wrong magic number, corruption) as opposed to a checksum error reported separately.","triggerScenarios":"Calling ZstdCompressor.uncompress on a byte array that is not a valid zstd frame — corrupt or truncated chunk data, wrong offsets (inputOffset/inputLength pointing at garbage), or data produced by a different compressor.","commonSituations":"Reading a damaged SSTable from failing disk; restoring a botched backup; pointing a reader at data compressed with a different algorithm; JNI/library version incompatibilities.","solutions":["Inspect the wrapped cause (getCause()) to see the exact zstd error and confirm whether data is corrupt or offsets are wrong.","Run `nodetool verify`/`scrub` on affected SSTables and repair from healthy replicas (`nodetool repair`).","Restore the affected files from backup, or confirm the chunk is being read with the correct compressor class and offsets."],"exampleFix":"// before: wrong offsets passed to uncompress\ncompressor.uncompress(buf, 0, buf.length, out, 0);\n// after: use the chunk's real compressed length\ncompressor.uncompress(buf, 0, compressedLength, out, 0);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    zstd.uncompress(input, inputOffset, inputLen, output, outputOffset);\n} catch (IOException e) {\n    logger.error(\"Zstd decompression failed: \" + e.getCause(), e);\n    // fail read, retry from another replica, or mark sstable corrupt\n}","preventionTips":["Always inspect getCause() to distinguish corruption from offset bugs.","Run `nodetool verify` regularly to find damaged SSTables before reads fail.","Ensure correct inputOffset/inputLength are taken from the chunk header."],"tags":["zstd","decompression","data-corruption","io"],"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"}