{"record":{"id":"e22fb4c98a39333b","repo":"t8y2/dbx","slug":"start-zookeeper-gssapi-negotiation-w","errorCode":null,"errorMessage":"start ZooKeeper GSSAPI negotiation: %w","messagePattern":"start ZooKeeper GSSAPI negotiation: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/argo-go/zookeeper_protocol.go","lineNumber":200,"sourceCode":"func zooKeeperTimeoutMillis(timeout time.Duration) int32 {\n\tmilliseconds := timeout.Milliseconds()\n\tif milliseconds < 1 {\n\t\treturn 1\n\t}\n\tif milliseconds > math.MaxInt32 {\n\t\treturn math.MaxInt32\n\t}\n\treturn int32(milliseconds)\n}\n\nfunc (client *protocolZooKeeperClient) authenticateSASL(saslClient zooKeeperSASLClient) error {\n\tif saslClient == nil {\n\t\treturn errors.New(\"ZooKeeper SASL client is nil\")\n\t}\n\tdefer saslClient.Dispose()\n\ttoken, err := saslClient.Start()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"start ZooKeeper GSSAPI negotiation: %w\", err)\n\t}\n\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() {","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/argo-go/zookeeper_protocol.go#L182-L218","documentation":"During SASL authentication, authenticateSASL calls saslClient.Start() to obtain the initial GSSAPI token; if the Kerberos/GSSAPI layer cannot begin the exchange (missing credentials, bad principal, no ticket), the error is wrapped as 'start ZooKeeper GSSAPI negotiation'. The SASL client is disposed on exit, and no SASL rounds are attempted when Start fails.","triggerScenarios":"authenticateSASL invoked (from newProtocolZooKeeperClient's auth flow after connect) when saslClient.Start() errors: no valid Kerberos TGT, wrong service principal for the ZooKeeper server, keytab/JAAS misconfiguration, or GSSAPI library initialization failure.","commonSituations":"Expired or missing kinit ticket in a long-running service; Kerberos realm/KDC unreachable from the container; service principal mismatch (zkclient/... vs zookeeper/... or cross-realm issues); krb5.conf not mounted into the pod; clock skew invalidating tickets.","solutions":["Run klist to confirm a valid, unexpired TGT; re-run kinit or refresh the keytab-based login","Verify the client principal and target service principal (zookeeper/host@REALM) and krb5.conf KDC settings","Ensure krb5.conf and the keytab are present and readable inside the container/pod","Check clock skew against the KDC (tickets fail with skew > ~5 minutes)","Enable GSSAPI/JAAS debug logging (-Dsun.security.krb5.debug=true) to see the exact Kerberos failure"],"exampleFix":"// before (container startup, no credentials)\nCMD [\"/app/server\"]\n// after\nCMD [\"kinit -kt /etc/krb5/zkclient.keytab zkclient@EXAMPLE.COM && /app/server\"]","handlingStrategy":"try-catch","validationCode":"func hasKerberosTicket() error {\n    // e.g. probe a fresh GSSAPI login before attempting the SASL handshake\n    cli, err := newSASLClient(service, host)\n    if err != nil { return fmt.Errorf(\"GSSAPI init failed (kinit?): %w\", err) }\n    cli.Dispose()\n    return nil\n}","typeGuard":null,"tryCatchPattern":"err := client.authenticateSASL(saslClient)\nif err != nil {\n    var gerr *gsasl.Error\n    if strings.Contains(err.Error(), \"start ZooKeeper GSSAPI negotiation\") {\n        // credentials problem: refresh ticket, then retry once\n        if rerr := refreshKeytabLogin(); rerr == nil {\n            err = client.authenticateSASL(newSASLClient(service, host))\n        }\n    }\n    return err\n}","preventionTips":["Refresh Kerberos tickets on a schedule (kinit -k -t keytab via cron/sidecar)","Mount krb5.conf and the keytab into containers with correct permissions","Validate the service principal name against the server's zoo.cfg principal","Monitor KDC reachability and clock sync (NTP) from client hosts"],"tags":["zookeeper","kerberos","sasl","gssapi","authentication"],"backgroundTag":"kerberos-auth-failed","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"}