t8y2/dbx · error

ZooKeeper connection event: %w

Error message

ZooKeeper connection event: %w

What it means

While waiting for the ZooKeeper session to be established, the event channel delivered a zk.Event carrying a non-nil Err. waitForZooKeeperSession aborts immediately and wraps the underlying error. This means the ZK client library reported a connection-level failure during the handshake instead of a normal state transition.

Source

Thrown at agents/drivers/argo-go/discovery.go:204

	}
	return "/" + strings.Join(cleaned, "/")
}

func waitForZooKeeperSession(ctx context.Context, events <-chan zk.Event, timeout time.Duration) error {
	timer := time.NewTimer(timeout)
	defer timer.Stop()
	for {
		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-timer.C:
			return errors.New("ZooKeeper connection timed out before a session was established")
		case event, ok := <-events:
			if !ok {
				return errors.New("ZooKeeper event stream closed before a session was established")
			}
			if event.Err != nil {
				return fmt.Errorf("ZooKeeper connection event: %w", event.Err)
			}
			switch event.State {
			case zk.StateHasSession:
				return nil
			case zk.StateAuthFailed:
				return errors.New("ZooKeeper authentication failed")
			case zk.StateExpired:
				return errors.New("ZooKeeper session expired during connection")
			}
		}
	}
}

func parseHiveServerRegistration(child string, data []byte) (endpoint, error) {
	candidates := []string{strings.TrimSpace(string(data)), strings.TrimSpace(child)}
	for _, candidate := range candidates {
		if candidate == "" {
			continue

View on GitHub (pinned to c0390bff16)

Solutions

  1. Inspect the wrapped error: if it is a dial error, verify the zooKeeper server list and network reachability (telnet/nc to host:2181).
  2. If TLS is configured, confirm the ensemble actually serves TLS and certificates/CA/ServerName are correct; remove zooKeeperTLSConfig for plaintext ensembles.
  3. Increase connectTimeout if the error indicates a timeout rather than refusal.
  4. Retry Endpoints() with backoff — ZK event errors during transient ensemble hiccups are often temporary.

Example fix

// before
tlsConfig := &tls.Config{...} // against plaintext ZK
// after
serviceDiscoveryMode=zookeeper, zooKeeperTLSConfig unset  // plaintext ensemble
Defensive patterns

Strategy: retry

Validate before calling

// preflight: TCP reachability of every ZK server
for _, addr := range zkAddresses {
    conn, err := net.DialTimeout("tcp", addr, 3*time.Second)
    if err != nil { return fmt.Errorf("ZooKeeper %s unreachable: %w", addr, err) }
    conn.Close()
}

Try / catch

err := waitForZooKeeperSession(ctx, events, timeout)
if err != nil {
    var zkErr error
    if errors.As(err, &zkErr) && strings.HasPrefix(err.Error(), "ZooKeeper connection event") {
        return retryWithBackoff(3) // transient handshake failure
    }
    return err
}

Prevention

When it happens

Trigger: An event with event.Err != nil arrives on the events channel from zk.Connect before a StateHasSession event — e.g. DNS/dial failure surfaced as an event, TLS handshake error, or protocol error from the ensemble.

Common situations: Wrong ZK host/port so every dial fails; TLS configured against a plaintext ZK (or vice versa) producing handshake errors in events; firewall dropping connections mid-handshake; ZK ensemble returning malformed responses due to version incompatibility.

Related errors


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