apache/cassandra · error · RuntimeException

Compression exception

Error message

Compression exception

What it means

While flushing a data chunk, CompressedSequentialWriter compresses the buffer via ICompressor.compress(). Compression is expected to be in-memory and infallible, so an IOException from the compressor is wrapped in a bare RuntimeException("Compression exception") — the comment notes it 'shouldn't happen'. Hitting it means the compressor implementation genuinely failed.

Source

Thrown at src/java/org/apache/cassandra/io/compress/CompressedSequentialWriter.java:216

    }

    @Override
    protected void flushData()
    {
        // resetAndTruncate leaves fchannel.position() past EOF after its verification reads + truncate;
        // re-seek so the next chunk lands at chunkOffset. No-op under linear writes.
        seekToChunkStart();

        try
        {
            // compressing data with buffer re-use
            buffer.flip();
            compressed.clear();
            compressor.compress(buffer, compressed);
        }
        catch (IOException e)
        {
            throw new RuntimeException("Compression exception", e); // shouldn't happen
        }

        int uncompressedLength = buffer.position();
        int compressedLength = compressed.position();
        uncompressedSize += uncompressedLength;
        ByteBuffer toWrite = compressed;
        if (compressedLength >= maxCompressedLength)
        {
            toWrite = buffer;
            if (uncompressedLength >= maxCompressedLength)
            {
                compressedLength = uncompressedLength;
            }
            else
            {
                // Pad the uncompressed data so that it reaches the max compressed length.
                // This could make the chunk appear longer, but this path is only reached at the end of the file, where
                // we use the file size to limit the buffer on reading.

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Inspect the wrapped IOException cause to identify which compressor failed and why
  2. Switch the compression algorithm on the table to a well-tested default (LZ4Compressor or SnappyCompressor) and rebuild/flush the affected SSTables
  3. Verify native library versions match the Cassandra build; force the Java implementation if the JNI library is suspect
  4. If a custom ICompressor is installed, fix its compress() contract (output buffer sizing, error handling) and add unit tests

Example fix

// before
CREATE TABLE ks.tbl (...) WITH compression = {'class': 'MyCustomCompressor'}; // buggy compress()
// after
ALTER TABLE ks.tbl WITH compression = {'class': 'LZ4Compressor'};
nodetool scrub ks tbl;
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check compressor roundtrip before relying on a custom implementation
ByteBuffer in = ByteBuffer.allocate(chunkSize);
ByteBuffer out = ByteBuffer.allocate(compressor.initialCompressedBufferLength(chunkSize));
compressor.compress(in, out); // must not throw for well-formed input

Try / catch

try {
    flushData();
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Compression exception")) {
        // inspect e.getCause() (IOException) — switch table compression to a standard impl and rebuild
    }
}

Prevention

When it happens

Trigger: flushData() invoking compressor.compress(buffer, compressed) on a chunk where the compressor implementation throws IOException — e.g. a buggy or custom ICompressor implementation, corrupted native compression library state (LZ4/Snappy/Deflate JNI), or an output buffer sized incorrectly for the compressed output.

Common situations: Custom or third-party compression implementations plugged into Cassandra; native library (liblz4/libsnappy) mismatches after upgrades; JVM transitions between native and pure-Java compressor variants.

Related errors


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