apache/kafka · error · SchemaException
The response is unrelated to Sasl request since its correlat
Error message
The response is unrelated to Sasl request since its correlation id is {responseCorrelationId} and the reserved range for Sasl request is [ {minReservedCorrelationId},{maxReservedCorrelationId}] What it means
Thrown as a SchemaException by NetworkClient.parseResponse when a CorrelationIdMismatchException is caught, the original request header's correlation id is inside the SASL reserved range, and the response's correlation id is NOT inside that reserved range. It signals that the bytes received during the SASL handshake do not belong to the SASL exchange at all, so the client refuses to feed them to the authenticator. The reserved range bounds are included so the mismatch is unambiguous.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/NetworkClient.java:925
*/
private LeastLoadedNode handleEmptyNodeList() {
if (bootstrapConfiguration == BootstrapConfiguration.DISABLED || metadataUpdater.isBootstrapped()) {
throw new IllegalStateException("There are no nodes in the Kafka cluster");
}
log.debug("No nodes available yet, still in bootstrap phase");
return new LeastLoadedNode(null, false);
}
public static AbstractResponse parseResponse(ByteBuffer responseBuffer, RequestHeader requestHeader) {
try {
return AbstractResponse.parseResponse(responseBuffer, requestHeader);
} catch (BufferUnderflowException e) {
throw new SchemaException("Buffer underflow while parsing response for request with header " + requestHeader, e);
} catch (CorrelationIdMismatchException e) {
if (SaslClientAuthenticator.isReserved(requestHeader.correlationId())
&& !SaslClientAuthenticator.isReserved(e.responseCorrelationId()))
throw new SchemaException("The response is unrelated to Sasl request since its correlation id is "
+ e.responseCorrelationId() + " and the reserved range for Sasl request is [ "
+ SaslClientAuthenticator.MIN_RESERVED_CORRELATION_ID + ","
+ SaslClientAuthenticator.MAX_RESERVED_CORRELATION_ID + "]");
else {
throw e;
}
}
}
/**
* Post process disconnection of a node
*
* @param responses The list of responses to update
* @param nodeId Id of the node to be disconnected
* @param now The current time
* @param disconnectState The state of the disconnected channel
*/
private void processDisconnection(List<ClientResponse> responses,View on GitHub (pinned to c31c9215e1)
Solutions
- Eliminate any proxy/sidecar between the client and broker during the SASL handshake, or ensure it preserves correlation ids verbatim.
- Confirm the SASL mechanism configured on the client is supported and identical to the broker (sasl.mechanism).
- Verify the JAAS config and credentials are correct so the broker accepts, not rejects, the SASL exchange.
- Upgrade broker and client to the latest patch release to pick up correlation-id/framing fixes.
- Capture a pcap of the handshake to confirm no third party is injecting frames onto the connection.
Example fix
// before: traffic routed through a rewriting L7 proxy
props.put("bootstrap.servers", "proxy.internal:443");
// after: direct to brokers, proxy bypassed for SASL
props.put("bootstrap.servers", "broker1:9093,broker2:9093"); Defensive patterns
Strategy: retry
Validate before calling
// This error is raised after a malformed SASL response arrives; nothing the caller sends can prevent it.
// Defensive pre-check: only expect SASL responses on connections mid-handshake.
if (!saslHandshakeInProgress(nodeId)) {
throw new IllegalStateException(
"Refusing to parse a SASL response for node " + nodeId + " - no handshake in flight");
} Type guard
// Narrow a response correlation id into the SASL-reserved band before trusting it.
public static boolean isReservedSaslCorrelation(int correlationId) {
return correlationId >= org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.MIN_RESERVED_CORRELATION_ID
&& correlationId <= org.apache.kafka.common.security.authenticator.SaslClientAuthenticator.MAX_RESERVED_CORRELATION_ID;
}
// If the inbound correlation id is outside the reserved band during a SASL exchange,
// the response is for a different (non-SASL) request — drop it. Try / catch
try {
AbstractResponse r = NetworkClient.parseResponse(buf, header);
} catch (org.apache.kafka.common.errors.SchemaException e) {
if (e.getMessage().startsWith("The response is unrelated to Sasl request")) {
// The channel interleaved a non-SASL response during handshake, typically after a reconnect.
// Re-authenticate: close the connection, re-handshake SASL, then retry the original request.
return reauthenticateAndRetry(node);
}
throw e;
} Prevention
- The error means a non-SASL response arrived on a channel mid-SASL-handshake — most often after a reconnect reused a correlation id.
- Ensure only one logical handshake runs per connection; do not pipeline application requests until SASL completes.
- On reconnect, always reset the authenticator state before sending new requests.
- If seen persistently, suspect a misbehaving proxy/LB rewriting frames between client and broker.
When it happens
Trigger: During SASL authentication, the broker (or an intermediary) sends a response whose correlation id falls outside the range reserved by SaslClientAuthenticator for in-flight SASL requests. This is caught in parseResponse only for requests whose correlation id was reserved; otherwise the raw CorrelationIdMismatchException is rethrown. Typical of a man-in-the-middle injecting traffic, a proxy that rewrites correlation ids, or a broker bug sending the wrong frame at the wrong time.
Common situations: A sidecar/proxy/load-balancer that rewrites or reorders frames between client and broker; SASL mechanism downgrade attacks where injected bytes are presented as the SASL response; broker version with a known framing regression during SASL handshake; rare race when the connection is reused across sessions and correlation id accounting drifts.
Related errors
- When the security.protocol configuration enables SASL, mecha
- `contextType` must be non-null if `securityProtocol` is `${s
- `clientSaslMechanism` must be non-null in client mode if `se
- `mode` must be non-null if `securityProtocol` is `${security
- Type ${principalBuilderClass.getName()} is not an instance o
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/2f35d479d78fb9c2.json.
Report an issue: GitHub.