t8y2/dbx · error
start ZooKeeper GSSAPI negotiation: %w
Error message
start ZooKeeper GSSAPI negotiation: %w
What it means
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.
Source
Thrown at agents/drivers/argo-go/zookeeper_protocol.go:200
func zooKeeperTimeoutMillis(timeout time.Duration) int32 {
milliseconds := timeout.Milliseconds()
if milliseconds < 1 {
return 1
}
if milliseconds > math.MaxInt32 {
return math.MaxInt32
}
return int32(milliseconds)
}
func (client *protocolZooKeeperClient) authenticateSASL(saslClient zooKeeperSASLClient) error {
if saslClient == nil {
return errors.New("ZooKeeper SASL client is nil")
}
defer saslClient.Dispose()
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() {View on GitHub (pinned to c0390bff16)
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
Example fix
// before (container startup, no credentials) CMD ["/app/server"] // after CMD ["kinit -kt /etc/krb5/zkclient.keytab zkclient@EXAMPLE.COM && /app/server"]
Defensive patterns
Strategy: try-catch
Validate before calling
func hasKerberosTicket() error {
// e.g. probe a fresh GSSAPI login before attempting the SASL handshake
cli, err := newSASLClient(service, host)
if err != nil { return fmt.Errorf("GSSAPI init failed (kinit?): %w", err) }
cli.Dispose()
return nil
} Try / catch
err := client.authenticateSASL(saslClient)
if err != nil {
var gerr *gsasl.Error
if strings.Contains(err.Error(), "start ZooKeeper GSSAPI negotiation") {
// credentials problem: refresh ticket, then retry once
if rerr := refreshKeytabLogin(); rerr == nil {
err = client.authenticateSASL(newSASLClient(service, host))
}
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- continue ZooKeeper GSSAPI negotiation at round %d: %w
- ZooKeeper session closed because SASL authentication is requ
- ZooKeeper session closed because SASL authentication is requ
- ZooKeeper SASL round %d: %w
- ZooKeeper GSSAPI negotiation exceeded %d rounds
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/e22fb4c98a39333b.
Report an issue: GitHub.