apache/cassandra · error · java.io.IOException
Compression failed
Error message
Compression failed
What it means
The ByteBuffer-based ZstdCompressorBase.compress wraps any exception from Zstd.compress(output, input, level, checksum-flag) in an IOException 'Compression failed'. zstd-jni throws mainly when the destination buffer is too small for the compressed result (compression cannot shrink data enough), meaning the caller mis-sized the output buffer.
Source
Thrown at src/java/org/apache/cassandra/io/compress/ZstdCompressorBase.java:162
}
}
/**
* Compress using ByteBuffers
*
* @param input
* @param output
* @throws IOException
*/
@Override
public void compress(ByteBuffer input, ByteBuffer output) throws IOException
{
try
{
Zstd.compress(output, input, compressionLevel(), ENABLE_CHECKSUM_FLAG);
} catch (Exception e)
{
throw new IOException("Compression failed", e);
}
}
/**
* Check if the given compression level is valid. This can be a negative value as well.
*
* @param level compression level
*/
public static void validateCompressionLevel(int level)
{
if (level < FAST_COMPRESSION_LEVEL || level > BEST_COMPRESSION_LEVEL)
{
throw new IllegalArgumentException(String.format("%s=%d is invalid", COMPRESSION_LEVEL_OPTION_NAME, level));
}
}
/**
* Get the supplied compression level; otherwise, use the defaultView on GitHub (pinned to 88fd0f6a0e)
Solutions
- Size the output buffer using Zstd.compressBound(inputLength) (or the compressor's initial/max compressed buffer length) rather than the input size.
- Give extra headroom for the frame header and checksum (ENABLE_CHECKSUM_FLAG adds bytes).
- Catch the IOException and inspect getCause() to confirm the failure is dstSize_tooSmall before changing buffer sizing.
Example fix
// before ByteBuffer out = ByteBuffer.allocate(input.remaining()); zstdCompressor.compress(out, input); // after ByteBuffer out = ByteBuffer.allocate((int) Zstd.compressBound(input.remaining())); zstdCompressor.compress(out, input);
Defensive patterns
Strategy: validation
Validate before calling
int outCap = (int) com.github.luben.zstd.Zstd.compressBound(input.remaining());
if (output.remaining() < outCap) throw new IllegalArgumentException("Output buffer too small: need " + outCap); Try / catch
try {
compressor.compress(output, input);
} catch (IOException e) {
if (e.getCause() != null && String.valueOf(e.getCause()).contains("dstSize")) {
output = ByteBuffer.allocate((int) Zstd.compressBound(input.remaining()));
} else throw e;
} Prevention
- Always size compression output buffers with Zstd.compressBound().
- Add headroom for frame header and checksum bytes.
- Test with incompressible data before deploying buffer sizing changes.
When it happens
Trigger: Calling compress(ByteBuffer, ByteBuffer) where the output buffer's remaining capacity is less than zstd's worst-case requirement (roughly input size + overhead for incompressible data, plus frame/checksum overhead).
Common situations: Allocating the output buffer exactly equal to input length or to the expected compressed size, then feeding highly incompressible (random/already-compressed) data; insufficient buffer headroom for the checksum flag.
Related errors
- Decompression failed due to
- Compression failed
- Compression exception
- Decompression failed
- Decompression failed due to
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/7ee4bded490de28d.
Report an issue: GitHub.