{"record":{"id":"2a8c55c332f42d9c","repo":"t8y2/dbx","slug":"zookeeper-sasl-response-is-truncated","errorCode":null,"errorMessage":"ZooKeeper SASL response is truncated","messagePattern":"ZooKeeper SASL response is truncated","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/zookeeper/sasl.go","lineNumber":133,"sourceCode":"\t}\n\treturn fmt.Errorf(\"ZooKeeper DIGEST-MD5 negotiation exceeded %d rounds\", zooKeeperSASLMaxRounds)\n}\n\nfunc zooKeeperSASLRound(connection net.Conn, xid int32, token []byte) ([]byte, error) {\n\tpayload := make([]byte, 12+len(token))\n\tbinary.BigEndian.PutUint32(payload[0:4], uint32(xid))\n\tbinary.BigEndian.PutUint32(payload[4:8], uint32(zooKeeperSASLOpcode))\n\tbinary.BigEndian.PutUint32(payload[8:12], uint32(len(token)))\n\tcopy(payload[12:], token)\n\tif err := writeZooKeeperFrame(connection, payload); err != nil {\n\t\treturn nil, err\n\t}\n\tresponse, err := readZooKeeperFrame(connection)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(response) < 20 {\n\t\treturn nil, errors.New(\"ZooKeeper SASL response is truncated\")\n\t}\n\tresponseXID := int32(binary.BigEndian.Uint32(response[4:8]))\n\tif responseXID != xid {\n\t\treturn nil, fmt.Errorf(\"ZooKeeper SASL response xid %d does not match request xid %d\", responseXID, xid)\n\t}\n\terrorCode := int32(binary.BigEndian.Uint32(response[16:20]))\n\tif errorCode != 0 {\n\t\treturn nil, fmt.Errorf(\"ZooKeeper SASL server returned error %d\", errorCode)\n\t}\n\tif len(response) < 24 {\n\t\treturn nil, errors.New(\"ZooKeeper SASL token is truncated\")\n\t}\n\ttokenLength := int(int32(binary.BigEndian.Uint32(response[20:24])))\n\tif tokenLength < 0 || tokenLength > zooKeeperMaximumFrameLen || 24+tokenLength > len(response) {\n\t\treturn nil, fmt.Errorf(\"ZooKeeper SASL token length %d is invalid\", tokenLength)\n\t}\n\treturn append([]byte(nil), response[24:24+tokenLength]...), nil\n}","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/zookeeper/sasl.go#L115-L151","documentation":"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.","triggerScenarios":"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.","commonSituations":"ZooKeeper server closing the connection abruptly, a proxy/load balancer cutting the stream, wrong port hitting a non-ZooKeeper service, or protocol version mismatches.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Check connectivity before SASL: TCP dial + initial server handshake\nc := net.DialTimeout(\"tcp\", addr, 5*time.Second)\nif c == nil { return errors.New(\"zookeeper unreachable\") }","typeGuard":null,"tryCatchPattern":"resp, err := zooKeeperSASLRound(conn, xid, token)\nif err != nil {\n    if strings.Contains(err.Error(), \"truncated\") {\n        // reconnect with fresh xid and bounded retries\n    }\n    return err\n}","preventionTips":["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)"],"tags":["zookeeper","sasl","network","protocol"],"backgroundTag":"truncated-response","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}