apache/cassandra · error · org.apache.cassandra.transport.ProtocolException
Provided frame does not appear to be LZ4 compressed
Error message
Provided frame does not appear to be LZ4 compressed
What it means
LZ4-compressed native-protocol frames begin with a 4-byte big-endian uncompressed-length prefix followed by the LZ4 block. If the body is shorter than 4 bytes, the server cannot even read the prefix and throws this ProtocolException.
Solutions
- Fix the client LZ4 framing: prefix each compressed body with the 4-byte big-endian uncompressed length.
- Disable compression in client connection options to avoid LZ4 framing entirely.
- Verify no intermediary truncates or rewrites the frame body.
- Upgrade to an official driver that implements the LZ4 codec correctly.
Example fix
// before: raw LZ4 block without length header body = lz4.block.compress(plain); // after byte[] compressed = lz4.block.compress(plain); buf.writeInt(plain.length); // 4-byte uncompressed length prefix buf.writeBytes(compressed);
Defensive patterns
Strategy: validation
Validate before calling
if (body.length < 4) throw new IllegalStateException("LZ4 frame requires a 4-byte uncompressed-length prefix");
int uncompressedLength = ((body[0]&0xFF)<<24)|((body[1]&0xFF)<<16)|((body[2]&0xFF)<<8)|(body[3]&0xFF); Type guard
boolean hasLz4Header(byte[] body) { return body != null && body.length >= 4; } Try / catch
try { ... } catch (ProtocolException e) {
if (e.getMessage().contains("LZ4")) { // disable compression or add 4-byte length prefix
}
} Prevention
- Prefix every LZ4-compressed body with a 4-byte big-endian uncompressed length.
- Round-trip test the LZ4 codec framing before deploying.
- Use the official driver's built-in LZ4 support rather than custom framing.
- Keep lz4 library versions consistent between build and runtime.
When it happens
Trigger: Client negotiates LZ4 compression but sends a body shorter than 4 bytes — empty body, plaintext body, or truncated frame.
Common situations: Client incorrectly enables lz4 without implementing the 4-byte length prefix; proxies/truncation; custom drivers writing raw LZ4 without the header.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid compressor type
- Invalid uncompressed frame length
- lz4-java was unable to load native libraries; this will…
- Provided frame does not appear to be Snappy compressed
- Snappy compression is not supported in protocol V5
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/5dbe200e468f4a78.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/transport/Compressor.java:205
catch (final Throwable e)
{
outputBuf.release();
throw e;
}
finally
{
uncompressed.release();
}
}
public Envelope decompress(Envelope compressed) throws IOException
{
try
{
byte[] input = CBUtil.readRawBytes(compressed.body);
if (input.length < INTEGER_BYTES)
throw new ProtocolException("Provided frame does not appear to be LZ4 compressed");
int uncompressedLength = ((input[0] & 0xFF) << 24)
| ((input[1] & 0xFF) << 16)
| ((input[2] & 0xFF) << 8)
| ((input[3] & 0xFF));
validateUncompressedLength(uncompressedLength);
ByteBuf output = CBUtil.allocator.heapBuffer(uncompressedLength);
try
{
int read = decompressor.decompress(input, INTEGER_BYTES, output.array(), output.arrayOffset(), uncompressedLength);
if (read != input.length - INTEGER_BYTES)
throw new IOException("Compressed lengths mismatch");
output.writerIndex(uncompressedLength);
return compressed.with(output);View on GitHub (pinned to 88fd0f6a0e)