{"record":{"id":"06f18c79346175da","repo":"t8y2/dbx","slug":"zookeeper-sent-an-unexpected-token-after-gssapi-co","errorCode":null,"errorMessage":"ZooKeeper sent an unexpected token after GSSAPI completion","messagePattern":"ZooKeeper sent an unexpected token after GSSAPI completion","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/argo-go/zookeeper_protocol.go","lineNumber":220,"sourceCode":"\tfor round := 0; round < zooKeeperMaxSASLRounds; round++ {\n\t\tresponse, requestErr := client.request(zooKeeperOpSASL, func(encoder *zooKeeperEncoder) {\n\t\t\tif token == nil {\n\t\t\t\tencoder.bytes([]byte{})\n\t\t\t\treturn\n\t\t\t}\n\t\t\tencoder.bytes(token)\n\t\t})\n\t\tif requestErr != nil {\n\t\t\treturn fmt.Errorf(\"ZooKeeper SASL round %d: %w\", round+1, requestErr)\n\t\t}\n\t\tdecoder := newZooKeeperDecoder(response)\n\t\tchallenge, decodeErr := decoder.bytes()\n\t\tif decodeErr != nil {\n\t\t\treturn fmt.Errorf(\"decode ZooKeeper SASL round %d: %w\", round+1, decodeErr)\n\t\t}\n\t\tif saslClient.Complete() {\n\t\t\tif len(challenge) != 0 {\n\t\t\t\treturn errors.New(\"ZooKeeper sent an unexpected token after GSSAPI completion\")\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\ttoken, err = saslClient.Step(challenge)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"continue ZooKeeper GSSAPI negotiation at round %d: %w\", round+1, err)\n\t\t}\n\t}\n\treturn fmt.Errorf(\"ZooKeeper GSSAPI negotiation exceeded %d rounds\", zooKeeperMaxSASLRounds)\n}\n\nfunc (client *protocolZooKeeperClient) AddAuth(scheme string, auth []byte) error {\n\t_, err := client.request(zooKeeperOpSetAuth, func(encoder *zooKeeperEncoder) {\n\t\tencoder.int32(0)\n\t\tencoder.string(scheme)\n\t\tencoder.bytes(auth)\n\t})\n\treturn err","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/argo-go/zookeeper_protocol.go#L202-L238","documentation":"During authenticateSASL, once the local GSSAPI client reports Complete(), the server must send no further SASL token. If an additional non-empty challenge arrives after completion, the protocol state is inconsistent and the client returns this error rather than feeding the completed negotiator another token.","triggerScenarios":"A misbehaving or non-conformant ZooKeeper server (or a proxy/interposer) sends an extra SASL challenge after the GSSAPI exchange finished; decoding a stale/duplicated SASL response frame; protocol version mismatch causing frame desynchronization.","commonSituations":"Connecting through a load balancer or proxy that replays buffered packets; ZooKeeper server versions with buggy SASL handling; mixed client/server SASL quorum settings causing spurious rounds.","solutions":["Verify you are connecting directly to a supported ZooKeeper version and not through a packet-rewriting proxy","Ensure client and server SASL configurations match (quorum.auth / server.auth settings)","Capture the exchange (packet logs) and check whether the extra token is a duplicated frame","Retry the connection — a transient desync in one session may not recur; if persistent, align server/client versions"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// no caller-side check; ensure direct connectivity to a supported ZooKeeper version\nif viaProxy {\n    log.Warn(\"SASL through proxies can produce extra tokens; connect directly if possible\")\n}","typeGuard":null,"tryCatchPattern":"err := zkClient.authenticateSASL(sasl)\nif err != nil && strings.Contains(err.Error(), \"unexpected token after GSSAPI completion\") {\n    // retry once with a fresh connection; if persistent, audit server/proxy SASL config\n}","preventionTips":["Connect directly to the ensemble, avoiding packet-rewriting proxies/LBs","Keep ZooKeeper server and client protocol versions aligned","Match client/server SASL (quorum.auth/server.auth) configuration","Capture packet traces when the error recurs to identify duplicated frames"],"tags":["zookeeper","sasl","gssapi","protocol","go"],"backgroundTag":"protocol-violation","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"}