t8y2/dbx · error

ZooKeeper Kerberos SASL requires Hive Kerberos credentials

Error message

ZooKeeper Kerberos SASL requires Hive Kerberos credentials

What it means

Kerberos-based ZooKeeper SASL requires Hive Kerberos credentials to run the GSSAPI negotiation. If config.Kerberos.Enabled is false, connectKerberosZooKeeper refuses to proceed because a plain connection would be rejected by a SASL-required ensemble (cf. code -124).

Source

Thrown at agents/drivers/hive-go/zookeeper_protocol.go:96

	options.CanonicalizeHost = config.ZooKeeperKerberos.CanonicalHostname
	options.ServerName = config.ZooKeeperKerberos.ServerPrincipal
	if options.ServerName == "" && config.ZooKeeperKerberos.Realm != "" {
		options.ServerName = service + "/_HOST@" + config.ZooKeeperKerberos.Realm
	}
	return service, options
}

func connectKerberosZooKeeper(
	servers []string,
	timeout time.Duration,
	tlsConfig *tls.Config,
	config connectionConfig,
) (zooKeeperClient, <-chan zk.Event, error) {
	if len(servers) == 0 {
		return nil, nil, errors.New("ZooKeeper server list is empty")
	}
	if !config.Kerberos.Enabled {
		return nil, nil, errors.New("ZooKeeper Kerberos SASL requires Hive Kerberos credentials")
	}
	ordered := append([]string(nil), servers...)
	shuffleZooKeeperServers(ordered)
	var failures []string
	for _, address := range ordered {
		host, _, err := net.SplitHostPort(address)
		if err != nil {
			failures = append(failures, fmt.Sprintf("%s: %v", address, err))
			continue
		}
		connection, err := dialZooKeeperConnection(address, timeout, tlsConfig)
		if err != nil {
			failures = append(failures, fmt.Sprintf("%s: %v", address, err))
			continue
		}
		client, err := newProtocolZooKeeperClient(connection, timeout)
		if err == nil {
			var saslClient zooKeeperSASLClient

View on GitHub (pinned to c0390bff16)

Solutions

  1. Set Kerberos.Enabled=true along with a valid Principal and Keytab in connectionConfig
  2. Provide the keytab file and ensure the principal exists in the KDC and is permitted by the ZooKeeper/Hive service
  3. Verify the config loader actually populates config.Kerberos from your connection string/env
  4. If SASL is not required, use the non-Kerberos connect path instead of connectKerberosZooKeeper

Example fix

// before
cfg := connectionConfig{Hosts: servers} // Kerberos zero-value: Enabled=false
conn, err := connectKerberosZooKeeper(ctx, servers, timeout, tls, cfg)
// after
cfg := connectionConfig{Hosts: servers}
cfg.Kerberos.Enabled = true
cfg.Kerberos.Principal = "hive/_HOST@EXAMPLE.COM"
cfg.Kerberos.Keytab = "/etc/security/keytabs/hive.keytab"
conn, err := connectKerberosZooKeeper(ctx, servers, timeout, tls, cfg)
Defensive patterns

Strategy: validation

Validate before calling

// Go
func kerberosReady(cfg connectionConfig) error {
    if !cfg.Kerberos.Enabled {
        return errors.New("kerberos must be enabled for SASL ZooKeeper")
    }
    if cfg.Kerberos.Principal == "" || cfg.Kerberos.Keytab == "" {
        return errors.New("kerberos principal and keytab are required")
    }
    if _, err := os.Stat(cfg.Kerberos.Keytab); err != nil {
        return fmt.Errorf("keytab missing: %w", err)
    }
    return nil
}

Prevention

When it happens

Trigger: Calling connectKerberosZooKeeper with a connectionConfig whose Kerberos.Enabled is false — Kerberos section omitted from config, disabled flag not set, or config not populated from the connection string.

Common situations: Using a service (Hive) that requires SASL ZooKeeper but deploying without keytab/principal configuration; config file has kerberos stanza but Enabled flag left false; environment variable wiring skipped during deployment.

Related errors


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