apache/cassandra · error · org.apache.cassandra.transport.ProtocolException
Invalid uncompressed frame length
Error message
Invalid uncompressed frame length %d; it must be non-negative and no greater than native_transport_max_frame_size (%d bytes)
What it means
When a client negotiates frame compression, each compressed frame starts with the uncompressed length. Compressor.validateUncompressedLength rejects values that are negative or exceed native_transport_max_frame_size, since decompressing them would be unsafe or exceed server limits.
Solutions
- Set native_transport_max_frame_size in cassandra.yaml to a value >= the client's maximum frame size (or lower the client's frame size).
- Fix the client to write the correct uncompressed length in the frame header before the compressed payload.
- Disable compression in the client connection options to isolate whether the compression framing is the problem.
- Upgrade the client driver to a version with correct LZ4/Snappy framing.
Example fix
// before (client): oversized frames
cassandra.yaml: native_transport_max_frame_size_in_mb: 16 vs client frame of 64MB
// after: align limits
cassandra.yaml: native_transport_max_frame_size_in_mb: 64
client: { frameWidth: 64 * 1024 * 1024, compression: 'lz4' } Defensive patterns
Strategy: validation
Validate before calling
int max = serverConfig.getNativeTransportMaxFrameSize();
if (uncompressedLength < 0 || uncompressedLength > max)
fail("frame exceeds server native_transport_max_frame_size: " + uncompressedLength); Type guard
boolean isFrameLengthSafe(int len, int maxFrameSize) { return len >= 0 && len <= maxFrameSize; } Try / catch
try { session.execute(query); } catch (ProtocolException e) {
if (e.getMessage().contains("native_transport_max_frame_size")) {
// reduce client frame size or raise server config
}
} Prevention
- Keep client max frame size <= server's native_transport_max_frame_size.
- Always write the uncompressed length header for compressed frames.
- Verify compression codec framing with a round-trip unit test.
- Check cassandra.yaml after upgrades, where defaults can change.
When it happens
Trigger: A compressed frame whose leading 4-byte uncompressed-length field is negative (bad LZ4/Snappy framing) or larger than native_transport_max_frame_size configured on the server.
Common situations: Client configured with compression but a frame size limit larger than the server's; a client writing a garbage/uninitialized length header; buggy third-party compression wrappers.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- chunk_length_in_kb must be a power of 2
- Invalid negative min_compress_ratio
- Invalid negative or null
- Invalid value for
- min_compress_ratio can either be 0 or greater than or equal…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/4f9c1b5d5bbbbee3.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/transport/Compressor.java:48
import io.netty.buffer.ByteBuf;
public interface Compressor
{
public Envelope compress(Envelope uncompressed) throws IOException;
public Envelope decompress(Envelope compressed) throws IOException;
/**
* Validates the uncompressed length declared in the header of a compressed frame before it is used to size a
* destination buffer.
*
* @param uncompressedLength the expected uncompressed length
* @throws ProtocolException when the uncompressed is negative, zero, or exceeds {@code native_transport_max_frame_size}
*/
static void validateUncompressedLength(int uncompressedLength)
{
int maxFrameSize = DatabaseDescriptor.getNativeTransportMaxFrameSize();
if (uncompressedLength < 0 || uncompressedLength > maxFrameSize)
throw new ProtocolException(String.format("Invalid uncompressed frame length %d; it must be non-negative and " +
"no greater than native_transport_max_frame_size (%d bytes)",
uncompressedLength, maxFrameSize));
}
/*
* TODO: We can probably do more efficient, like by avoiding copy.
* Also, we don't reuse ICompressor because the API doesn't expose enough.
*/
public static class SnappyCompressor implements Compressor
{
public static final SnappyCompressor instance;
static
{
SnappyCompressor i;
try
{
i = new SnappyCompressor();
}View on GitHub (pinned to 88fd0f6a0e)