t8y2/dbx · error

ZooKeeper SASL client is nil

Error message

ZooKeeper SASL client is nil

What it means

protocolZooKeeperClient.authenticateSASL requires a non-nil zooKeeperSASLClient; passing nil returns this error before Dispose or any negotiation begins. The SASL client drives the GSSAPI challenge/response rounds, so without it Kerberos authentication cannot proceed.

Source

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

		return nil, zk.ErrSessionExpired
	}
	return client, nil
}

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)

View on GitHub (pinned to c0390bff16)

Solutions

  1. Ensure the GSSAPI/SASL client is constructed from valid Kerberos credentials before calling authenticateSASL
  2. Fix the factory that produced a nil client without an error
  3. Skip authenticateSASL only when the server does not require SASL — never pass nil to satisfy the signature
  4. Add an assertion/check at the call site for a nil SASL client

Example fix

// before
sasl := buildSASLClient(cfg) // may return nil
err := zkClient.authenticateSASL(sasl)
// after
sasl := buildSASLClient(cfg)
if sasl == nil {
    return errors.New("failed to build ZooKeeper SASL client from Kerberos credentials")
}
err := zkClient.authenticateSASL(sasl)
Defensive patterns

Strategy: validation

Validate before calling

if saslClient == nil {
    return errors.New("SASL client not initialized; check Kerberos credential loading")
}

Type guard

func hasSASLClient(c zooKeeperSASLClient) bool { return c != nil }

Try / catch

if err := zkClient.authenticateSASL(sasl); err != nil {
    if strings.Contains(err.Error(), "SASL client is nil") {
        // rebuild the SASL client from credentials and retry
    }
}

Prevention

When it happens

Trigger: Calling authenticateSASL(nil), or passing a SASL client variable that was never initialized because credential loading (keytab/ccache) failed silently upstream.

Common situations: Lazy initialization of the GSSAPI client that was skipped on an error path; test doubles not wired in; factory functions returning nil instead of an error when Kerberos credentials are missing.

Related errors


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