t8y2/dbx · error

ZooKeeper GSSAPI negotiation exceeded %d rounds

Error message

ZooKeeper GSSAPI negotiation exceeded %d rounds

What it means

The SASL/GSSAPI exchange did not complete within the library's hard cap of zooKeeperMaxSASLRounds (8) request/response round trips, so authenticateSASL aborts to prevent an infinite loop. A legitimate Kerberos handshake finishes in 2-4 legs; exceeding 8 rounds means the server keeps challenging without ever signaling context completion, typically because authentication is being rejected or a non-GSSAPI peer is on the other end.

Source

Thrown at agents/drivers/argo-go/zookeeper_protocol.go:229

			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() {
			if len(challenge) != 0 {
				return errors.New("ZooKeeper sent an unexpected token after GSSAPI completion")
			}
			return nil
		}
		token, err = saslClient.Step(challenge)
		if err != nil {
			return fmt.Errorf("continue ZooKeeper GSSAPI negotiation at round %d: %w", round+1, err)
		}
	}
	return fmt.Errorf("ZooKeeper GSSAPI negotiation exceeded %d rounds", zooKeeperMaxSASLRounds)
}

func (client *protocolZooKeeperClient) AddAuth(scheme string, auth []byte) error {
	_, err := client.request(zooKeeperOpSetAuth, func(encoder *zooKeeperEncoder) {
		encoder.int32(0)
		encoder.string(scheme)
		encoder.bytes(auth)
	})
	return err
}

func (client *protocolZooKeeperClient) Children(path string) ([]string, *zk.Stat, error) {
	response, err := client.request(zooKeeperOpGetChildren2, func(encoder *zooKeeperEncoder) {
		encoder.string(path)
		encoder.boolean(false)
	})
	if err != nil {
		return nil, nil, err

View on GitHub (pinned to c0390bff16)

Solutions

  1. Verify the ZooKeeper server has SASL authentication enabled and expects GSSAPI (check jaas.conf, authProvider config, and server logs for 'SASL authentication failed' entries).
  2. Confirm you are connecting to port 2181 of an actual ZooKeeper member, not another service or a misplaced proxy.
  3. Compare the client mechanism with the server's configured mechanism (GSSAPI vs DIGEST-MD5) and align JAAS/krb5 configuration on both sides.
  4. Check server logs during connection: an auth failure being replayed as a challenge is the usual cause; fix the underlying credential/principal problem.
  5. If your Kerberos setup legitimately requires more legs (rare, multi-hop), the cap is fixed at 8 in this driver — reduce handshake complexity (single-hop realm).

Example fix

// before: server without SASL configured
hosts := "zk-nosasl.internal:2181" // negotiation exceeds 8 rounds
// after: point at SASL-enabled quorum (server jaas.conf with QuorumServer/Server sections)
hosts := "zk-sasl-1.internal:2181,zk-sasl-2.internal:2181"
Defensive patterns

Strategy: validation

Validate before calling

// Before connecting, confirm the endpoint is a SASL-capable ZooKeeper
conn, err := net.DialTimeout("tcp", "zk-host:2181", 3*time.Second)
if err != nil {
    return err
}
conn.Close()
// and verify server config out-of-band (4lw 'srvr' or admin API) shows auth_enabled / sasl.enabled

Try / catch

if err := client.Connect(); err != nil {
    if strings.Contains(err.Error(), "exceeded 8 rounds") {
        return fmt.Errorf("server likely has SASL disabled or mechanism mismatch; check server jaas.conf and port: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: authenticateSASL loops the full 8 iterations with saslClient.Complete() never returning true and Step never erroring — the server persistently replies with challenges that the local GSSAPI mechanism keeps answering (e.g. server not actually performing SASL auth, echoing tokens, or an auth failure that surfaces as another challenge instead of an error).

Common situations: Pointing the client at a ZooKeeper server (or wrong port, e.g. a different service) that does not have SASL enabled while the client attempts GSSAPI, server/client mechanism mismatch (server expects DIGEST-MD5 while client runs GSSAPI), or a mid-handshake auth failure the server reports as a continued challenge.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/ab51debbb8d0b00d. Report an issue: GitHub.