t8y2/dbx · error
decode ZooKeeper SASL round %d: %w
Error message
decode ZooKeeper SASL round %d: %w
What it means
This error occurs when the client cannot decode the SASL challenge bytes from a ZooKeeper SASL response frame. After each SASL request, authenticateSASL parses the reply expecting a length-prefixed token (the GSSAPI challenge); a decode failure means the response payload is shorter or malformed relative to the expected wire format. It usually signals a protocol mismatch or a corrupt/abridged response.
Source
Thrown at agents/drivers/argo-go/zookeeper_protocol.go:216
token, err := saslClient.Start()
if err != nil {
return fmt.Errorf("start ZooKeeper GSSAPI negotiation: %w", err)
}
for round := 0; round < zooKeeperMaxSASLRounds; round++ {
response, requestErr := client.request(zooKeeperOpSASL, func(encoder *zooKeeperEncoder) {
if token == nil {
encoder.bytes([]byte{})
return
}
encoder.bytes(token)
})
if requestErr != nil {
return fmt.Errorf("ZooKeeper SASL round %d: %w", round+1, requestErr)
}
decoder := newZooKeeperDecoder(response)
challenge, decodeErr := decoder.bytes()
if decodeErr != nil {
return fmt.Errorf("decode ZooKeeper SASL round %d: %w", round+1, decodeErr)
}
if saslClient.Complete() {
if len(challenge) != 0 {
return errors.New("ZooKeeper sent an unexpected token after GSSAPI completion")
}
return nil
}
token, err = saslClient.Step(challenge)
if err != nil {
return fmt.Errorf("continue ZooKeeper GSSAPI negotiation at round %d: %w", round+1, err)
}
}
return fmt.Errorf("ZooKeeper GSSAPI negotiation exceeded %d rounds", zooKeeperMaxSASLRounds)
}
func (client *protocolZooKeeperClient) AddAuth(scheme string, auth []byte) error {
_, err := client.request(zooKeeperOpSetAuth, func(encoder *zooKeeperEncoder) {
encoder.int32(0)View on GitHub (pinned to c0390bff16)
Solutions
- Read the wrapped inner decode error to see whether the frame length exceeds the payload (truncation) — then check for proxies/NAT in front of ZooKeeper and connect directly to the quorum.
- Confirm the ZooKeeper server version supports the SASL opcode with the same framing the client implements; upgrade the server or the client driver to matching versions.
- Close and re-establish the connection: a desynced TCP stream after an earlier failure will keep producing malformed frames.
- Check server logs for errors around the SASL round to see what the server actually replied.
- Retry with a longer timeout in case a partial read due to a short deadline produced a short frame.
Example fix
// before: proxy strips frames
connectErr := connect("zk-lb.internal:2181") // decode ZooKeeper SASL round 1: unexpected EOF
// after: connect directly to quorum members
connectErr := connect("zk-1.internal:2181,zk-2.internal:2181,zk-3.internal:2181") Defensive patterns
Strategy: retry
Try / catch
err := client.Get(path)
if err != nil && strings.Contains(err.Error(), "decode ZooKeeper SASL round") {
// malformed frame — stream may be corrupt; do NOT reuse the connection
client.Close()
return redialAndRetry(path, 1)
}
return err Prevention
- Connect directly to ZooKeeper quorum members instead of through proxies that can truncate frames.
- Use matching client/server driver versions supporting the same SASL framing.
- Redial after any framing/decode error instead of continuing on a desynced stream.
- Monitor for repeated decode failures from one endpoint — a sign of a broken middlebox.
When it happens
Trigger: During authenticateSASL, decoder.bytes() on the response of a zooKeeperOpSASL request fails because the response payload contains fewer bytes than its declared length prefix or is empty — e.g. an incompatible ZooKeeper server version, a proxy that truncates frames, or a server replying with an unexpected error body instead of a SASL token.
Common situations: Connecting through a load balancer/proxy that mangles ZooKeeper frames, mismatched ZooKeeper server protocol (older server not supporting the SASL opcode body format the client expects), or corrupted responses when the connection state desyncs after a prior failed request on the same TCP connection.
Related errors
- ZooKeeper sent an unexpected token after GSSAPI completion
- ZooKeeper GSSAPI negotiation exceeded %d rounds
- ZooKeeper session closed because SASL authentication is requ
- ZooKeeper Kerberos SASL requires Hive Kerberos credentials
- ZooKeeper SASL client is nil
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/a794ce8122570120.
Report an issue: GitHub.