apache/cassandra · error · ProtocolException

Unsupported compressor:

Error message

Unsupported compressor: 

What it means

InitialHandler.frameDecoder() selects the inbound FrameDecoder based on the connection's compressor; only null (none) and LZ4 are supported. If the negotiated compressor is anything else (e.g. Snappy configured via StartupOptions), it throws ProtocolException("Unsupported compressor: <class>").

Solutions

  1. Use COMPRESSION=lz4 in the client's startup options instead of snappy.
  2. Omit compression entirely (no COMPRESSION option) when using SimpleClient.
  3. If snappy is required, add a FrameDecoderSnappy branch to frameDecoder() mirroring the LZ4 path.
  4. Prefer the official java driver, which supports snappy natively.

Example fix

// before
options.put(StartupOptions.COMPRESSION, "snappy");
// after
options.put(StartupOptions.COMPRESSION, "lz4");
Defensive patterns

Strategy: validation

Validate before calling

String comp = startupOptions.get(StartupOptions.COMPRESSION);
if (comp != null && !"lz4".equalsIgnoreCase(comp))
    throw new IllegalArgumentException("SimpleClient supports only lz4 or no compression, got: " + comp);

Try / catch

try { connect(); } catch (ProtocolException e) { if (e.getMessage().startsWith("Unsupported compressor")) { disableCompression(); reconnect(); } }

Prevention

When it happens

Trigger: Client sets COMPRESSION=snappy (or another algorithm) in STARTUP options against SimpleClient, whose frameDecoder only implements no-compression and LZ4.

Common situations: Copying client options that specify snappy compression (common with drivers) into the simple test client; mismatch between server-accepted compression and what the test client's pipeline can decode.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/transport/SimpleClient.java:619

                        flusher.enqueue(message.encode(version, outboundStreamId(message)));

                    flusher.maybeWrite(ctx, promise);
                }
            });
            pipeline.remove(this);

            Message.Response message = messageDecoder.decode(ctx.channel(), request);
            responseConsumer.dispatch(channel, message, (p, ch, req, resp) -> null, null, Overload.NONE);
        }

        private FrameDecoder frameDecoder(ChannelHandlerContext ctx, BufferPoolAllocator allocator)
        {
            Connection conn = ctx.channel().attr(Connection.attributeKey).get();
            if (conn.getCompressor() == null)
                return FrameDecoderCrc.create(allocator);
            if (conn.getCompressor() instanceof Compressor.LZ4Compressor)
                return FrameDecoderLZ4.fast(allocator);
            throw new ProtocolException("Unsupported compressor: " + conn.getCompressor().getClass().getCanonicalName());
        }

        private FrameEncoder frameEncoder(ChannelHandlerContext ctx)
        {
            Connection conn = ctx.channel().attr(Connection.attributeKey).get();
            if (conn.getCompressor() == null)
                return FrameEncoderCrc.instance;
            if (conn.getCompressor() instanceof Compressor.LZ4Compressor)
                return FrameEncoderLZ4.fastInstance;
            throw new ProtocolException("Unsupported compressor: " + conn.getCompressor().getClass().getCanonicalName());
        }

        private void configureLegacyPipeline(ChannelHandlerContext ctx)
        {
            logger.info("Configuring legacy pipeline");
            ChannelPipeline pipeline = ctx.pipeline();
            pipeline.remove(this);
            pipeline.addAfter(HandlerNames.ENVELOPE_ENCODER, HandlerNames.DECOMPRESSOR, Envelope.Decompressor.instance);

View on GitHub (pinned to 88fd0f6a0e)