{"record":{"id":"6d3ed9ffcc930607","repo":"apache/cassandra","slug":"round-trip-mismatch-compressed-with-s-decompres","errorCode":null,"errorMessage":"Round-trip mismatch: compressed with %s, decompressed with %s","messagePattern":"Round-trip mismatch: compressed with (.+?), decompressed with (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/service/StartupChecks.java","lineNumber":486,"sourceCode":"            compressed.flip();\n\n            // Within a compress/uncompress call the in/out buffers must share a type, but the compressor\n            // and decompressor may prefer different ones; only re-stage the compressed bytes in that case.\n            if (compressor.preferredBufferType() != decompressor.preferredBufferType())\n            {\n                ByteBuffer staged = decompressor.preferredBufferType().allocate(compressed.remaining());\n                staged.put(compressed);\n                staged.flip();\n                compressed = staged;\n            }\n\n            ByteBuffer output = decompressor.preferredBufferType().allocate(payload.length);\n            decompressor.uncompress(compressed, output);\n            output.flip();\n\n            if (!output.equals(ByteBuffer.wrap(payload)))\n            {\n                throw new IOException(String.format(\"Round-trip mismatch: compressed with %s, decompressed with %s\",\n                                                    compressor.getClass().getName(), decompressor.getClass().getName()));\n            }\n        }\n        private byte[] smokeTestPayload(Random random)\n        {\n            // 4 KiB payload: the first half zeros (highly compressible, exercises the real compression\n            // path), the second half high-entropy bytes (incompressible, exercises the compressor's\n            // worst-case output sizing via initialCompressedBufferLength).\n            byte[] testPayload = new byte[4 * 1024];\n            byte[] randomHalf = new byte[testPayload.length / 2];\n            random.nextBytes(randomHalf);\n            System.arraycopy(randomHalf, 0, testPayload, testPayload.length / 2, randomHalf.length);\n            return testPayload;\n        }\n    };\n\n    public static final StartupCheck checkValidLaunchDate = new StartupCheck()\n    {","sourceCodeStart":468,"sourceCodeEnd":504,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/StartupChecks.java#L468-L504","documentation":"During the compression provider smoke test, a payload compressed by the provider's compressor is decompressed by the built-in (or vice versa) and compared to the original. If decompression yields different bytes, an IOException 'Round-trip mismatch' is thrown, indicating the provider's codec is not interoperable with the built-in it substitutes for.","triggerScenarios":"assertCompatibleRoundTrip(): compress with compressor, uncompress with decompressor, output ByteBuffer != ByteBuffer.wrap(payload) — for deterministic seeded payloads.","commonSituations":"Provider codec produces a valid-but-different format, trailing bytes/padding handled differently, provider truncated or padded the buffer differently than the built-in expects.","solutions":["Fix the provider's compress/uncompress so the built-in can decompress its output byte-identically (and vice versa)","Compare output buffers byte-by-byte with the reported inputs to locate the first differing byte","Test with the seeded smokeTestPayload payloads used by StartupChecks","Drop the provider registration if true interoperability cannot be achieved"],"exampleFix":"// before\noutput.flip(); return output; // leftover padding bytes included in comparison\n// after\noutput.flip();\noutput.limit(uncompressedSize); // only the actual payload bytes\nreturn output;","handlingStrategy":"validation","validationCode":"byte[] c = provider.uncompress(builtin.compress(payload)); assert Arrays.equals(c, payload); // and the reverse direction","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Test both directions (provider->builtin and builtin->provider)","Use the same seeded payloads as StartupChecks in provider CI","Handle buffer limits/flip semantics exactly as the built-in does"],"tags":["compression","provider","round-trip","data-corruption"],"backgroundTag":"checksum-mismatch","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}