t8y2/dbx · error

ZooKeeper server list is empty

Error message

ZooKeeper server list is empty

What it means

connectKerberosZooKeeper validates the server list before attempting any connection. An empty list means there is no ensemble member to dial, so the function fails fast with this error instead of shuffling and iterating zero hosts.

Source

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

	options.QOP = "auth"
	options.AuthorizationID = ""
	options.ServiceHost = ""
	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
		}

View on GitHub (pinned to c0390bff16)

Solutions

  1. Populate the ZooKeeper server list in the connection config (host1:2181,host2:2181,...)
  2. Verify discovery/Helm/env config actually yields ZooKeeper endpoints before dialing
  3. Add a caller-side precheck for len(servers) > 0 to produce a clearer config error
  4. If hosts come from an upstream service, log the raw source value to see why it parsed empty

Example fix

// before
zkHosts := os.Getenv("ZOOKEEPER_HOSTS") // ""
conn, err := connectKerberosZooKeeper(ctx, strings.Split(zkHosts, ","), timeout, tls, cfg)
// after
zkHosts := os.Getenv("ZOOKEEPER_HOSTS")
if zkHosts == "" {
    return fmt.Errorf("ZOOKEEPER_HOSTS must be set")
}
conn, err := connectKerberosZooKeeper(ctx, strings.Split(zkHosts, ","), timeout, tls, cfg)
Defensive patterns

Strategy: validation

Validate before calling

hosts := parseZooKeeperHosts(cfg.ZooKeeperHosts)
if len(hosts) == 0 {
    return errors.New("at least one ZooKeeper host is required")
}

Prevention

When it happens

Trigger: Calling connectKerberosZooKeeper with servers == nil or len(servers)==0 — typically because the ZooKeeper discovery hosts string was empty or parsed to nothing.

Common situations: Connection string like zk= with no hosts; DNS/service-discovery returned no ZooKeeper endpoints; config key omitted entirely while Kerberos is enabled.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


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