t8y2/dbx · error

ZooKeeper SASL client is nil

Error message

ZooKeeper SASL client is nil

What it means

authenticateSASL runs the GSSAPI/SASL handshake with the ZooKeeper server and requires a non-nil zooKeeperSASLClient to generate tokens. A nil SASL client means there is no negotiation implementation, so the function fails fast before attempting Start().

Source

Thrown at agents/drivers/hive-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. Construct the SASL client with valid Kerberos credentials before calling authenticateSASL, and check its construction error
  2. Avoid typed-nil interfaces: return (nil, err) or a real client, never a nil pointer stored in the interface
  3. Ensure the Kerberos ticket/keytab is available in the environment (KRB5CCNAME, keytab path)
  4. If authentication is not intended, use a non-SASL connect path instead of authenticateSASL

Example fix

// before
var sasl zooKeeperSASLClient // nil
if err := client.authenticateSASL(sasl); err != nil { ... }
// after
sasl, err := newKerberosSASLClient(principal, keytab)
if err != nil {
    return fmt.Errorf("build SASL client: %w", err)
}
if err := client.authenticateSASL(sasl); err != nil { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Go
if saslClient == nil {
    return errors.New("SASL client must be constructed with valid Kerberos credentials")
}
if err := client.authenticateSASL(saslClient); err != nil { ... }

Type guard

// Go
func hasSASL(c zooKeeperSASLClient) bool {
    return c != nil // catches nil interface; also avoid storing typed nils
}

Prevention

When it happens

Trigger: Calling client.authenticateSASL(nil) or passing an uninitialized/typed-nil SASL client variable (e.g. a nil *kerberosSASLClient stored in an interface).

Common situations: Kerberos credentials failed to load so the SASL client constructor returned nil and the error was swallowed; a build without Kerberos support yields a nil client; test harness omits the client.

Related errors


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