apache/cassandra · error · ProtocolException

Unexpected REQUEST message

Error message

Unexpected REQUEST message %s, expecting RESPONSE

What it means

ProtocolException thrown by Message.Decoder's ResponseDecoder when a frame is a REQUEST-direction message on a connection where RESPONSE messages are expected — i.e. the server's own outbound/response decoding path received something shaped like a client request. It guards the symmetry of the protocol: each side must send only its assigned direction. The frame is rejected before processing.

Solutions

  1. Ensure the decoding side actually expects responses (use RequestDecoder on the server, ResponseDecoder only on client-side connections).
  2. Fix the peer that is sending REQUEST-direction messages on a response channel.
  3. Reconnect to resynchronize corrupted streams.
  4. Check test/integration harnesses for swapped decoder wiring.

Example fix

// before: client-side pipeline decodes with the wrong decoder
pipeline.addLast(new Message.Decoder.ResponseDecoder()); // server sends us responses, wrong slot
// after: clients decode responses, requests are only what we send
pipeline.addLast(new Message.Decoder.RequestDecoder()); // as a server receiving requests
Defensive patterns

Strategy: try-catch

Try / catch

try { frame = decoder.decode(ch, envelope); } catch (ProtocolException e) { log.warn("Wrong-direction frame from peer: {}", e.getMessage()); close(ch); }

Prevention

When it happens

Trigger: ResponseDecoder.decode receives an Envelope whose header.type.direction != Direction.RESPONSE, typically when a server-side component (e.g. an internode or testing client) decodes an inbound frame containing QUERY, STARTUP, etc. where a response was expected.

Common situations: Using the server's internal client classes against a peer that sends requests back, corrupted frames in-flight, or test harnesses wiring decoders on the wrong side of a connection.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/transport/Message.java:502

        private static class RequestDecoder extends Decoder<Request>
        {
            Request decode(Channel channel, Envelope request)
            {
                if (request.header.type.direction != Direction.REQUEST)
                    throw new ProtocolException(String.format("Unexpected RESPONSE message %s, expecting REQUEST",
                                                              request.header.type));

                return (Request) decodeMessage(channel, request);
            }
        }

        private static class ResponseDecoder extends Decoder<Response>
        {
            Response decode(Channel channel, Envelope response)
            {
                if (response.header.type.direction != Direction.RESPONSE)
                    throw new ProtocolException(String.format("Unexpected REQUEST message %s, expecting RESPONSE",
                                                              response.header.type));

                return (Response) decodeMessage(channel, response);
            }
        }
    }

    private static final Decoder.RequestDecoder REQUEST_DECODER = new Decoder.RequestDecoder();
    private static final Decoder.ResponseDecoder RESPONSE_DECODER = new Decoder.ResponseDecoder();

    static Decoder<Message.Request> requestDecoder()
    {
        return REQUEST_DECODER;
    }

    static Decoder<Message.Response> responseDecoder()
    {
        return RESPONSE_DECODER;

View on GitHub (pinned to 88fd0f6a0e)