t8y2/dbx · error
ZooKeeper SASL response is truncated
Error message
ZooKeeper SASL response is truncated
What it means
zooKeeperSASLRound validates that a SASL response frame contains at least the 20-byte ZooKeeper response header (length, xid, zxid, error code). A shorter frame means the server sent a malformed or truncated response, so it cannot even be parsed for the error code.
Source
Thrown at agents/drivers/zookeeper/sasl.go:133
}
return fmt.Errorf("ZooKeeper DIGEST-MD5 negotiation exceeded %d rounds", zooKeeperSASLMaxRounds)
}
func zooKeeperSASLRound(connection net.Conn, xid int32, token []byte) ([]byte, error) {
payload := make([]byte, 12+len(token))
binary.BigEndian.PutUint32(payload[0:4], uint32(xid))
binary.BigEndian.PutUint32(payload[4:8], uint32(zooKeeperSASLOpcode))
binary.BigEndian.PutUint32(payload[8:12], uint32(len(token)))
copy(payload[12:], token)
if err := writeZooKeeperFrame(connection, payload); err != nil {
return nil, err
}
response, err := readZooKeeperFrame(connection)
if err != nil {
return nil, err
}
if len(response) < 20 {
return nil, errors.New("ZooKeeper SASL response is truncated")
}
responseXID := int32(binary.BigEndian.Uint32(response[4:8]))
if responseXID != xid {
return nil, fmt.Errorf("ZooKeeper SASL response xid %d does not match request xid %d", responseXID, xid)
}
errorCode := int32(binary.BigEndian.Uint32(response[16:20]))
if errorCode != 0 {
return nil, fmt.Errorf("ZooKeeper SASL server returned error %d", errorCode)
}
if len(response) < 24 {
return nil, errors.New("ZooKeeper SASL token is truncated")
}
tokenLength := int(int32(binary.BigEndian.Uint32(response[20:24])))
if tokenLength < 0 || tokenLength > zooKeeperMaximumFrameLen || 24+tokenLength > len(response) {
return nil, fmt.Errorf("ZooKeeper SASL token length %d is invalid", tokenLength)
}
return append([]byte(nil), response[24:24+tokenLength]...), nil
}View on GitHub (pinned to c0390bff16)
Solutions
- Check ZooKeeper server logs for connection resets or auth failures at the same time
- Verify the client is pointed at the correct ZooKeeper client port (default 2181) and not a proxy or admin port
- Retry the connection; transient truncation often indicates network interruption
- Upgrade driver/server if the server is an unusual build sending short SASL responses
Defensive patterns
Strategy: retry
Validate before calling
// Check connectivity before SASL: TCP dial + initial server handshake
c := net.DialTimeout("tcp", addr, 5*time.Second)
if c == nil { return errors.New("zookeeper unreachable") } Try / catch
resp, err := zooKeeperSASLRound(conn, xid, token)
if err != nil {
if strings.Contains(err.Error(), "truncated") {
// reconnect with fresh xid and bounded retries
}
return err
} Prevention
- Monitor ZooKeeper server logs for resets during auth
- Avoid proxies between client and ZooKeeper client port
- Use session timeouts generous enough for SASL negotiation
- Point clients at the real client port (2181), not admin (8080)
When it happens
Trigger: readZooKeeperFrame returns a response shorter than 20 bytes during the SASL negotiation round, e.g. when the server closes mid-frame or sends a non-SASL response.
Common situations: ZooKeeper server closing the connection abruptly, a proxy/load balancer cutting the stream, wrong port hitting a non-ZooKeeper service, or protocol version mismatches.
Related errors
- ZooKeeper sent an unexpected token after GSSAPI completion
- ZooKeeper sent an unexpected token after GSSAPI completion
- ZooKeeper sent an unexpected token after DIGEST-MD5 completi
- ZooKeeper DIGEST-MD5 completed with an unexpected client tok
- ZooKeeper SASL token is truncated
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/2a8c55c332f42d9c.
Report an issue: GitHub.