apache/cassandra · error · ProtocolException
Unexpected REQUEST message %s, expecting RESPONSE
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.
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)
Solutions
- Ensure the decoding side actually expects responses (use RequestDecoder on the server, ResponseDecoder only on client-side connections).
- Fix the peer that is sending REQUEST-direction messages on a response channel.
- Reconnect to resynchronize corrupted streams.
- 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
- Wire RequestDecoder on the server side and ResponseDecoder only where responses are expected
- Use one decoder type per connection side
- Verify test harnesses use the correct decoder for their role
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
- Wrong protocol direction (expected %s, got %s) for opcode %d
- Unexpected RESPONSE message %s, expecting REQUEST
- Configured ${configName} "${intf}" could not be found
- Configured ${configName} "${intf}" was found, but had no add
- Configured ${configName} "${intf}" caused an exception
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/17d53c2c832aa478.
Report an issue: GitHub.