t8y2/dbx · error

ZooKeeper connection event: %w

Error message

ZooKeeper connection event: %w

What it means

While waiting for the ZooKeeper session to establish, the watch event channel delivered an event carrying a non-nil Err. The library wraps that underlying connection error with %w so the root cause (DNS failure, connection refused, TLS error, etc.) remains inspectable via errors.Is/As.

Source

Thrown at agents/drivers/hive-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. Unwrap with errors.Is/As to identify the underlying connection error and fix that cause first.
  2. Verify the ZooKeeper connection string hosts/ports are reachable (nc/zkCli from the client host).
  3. Increase the connect timeout if the ensemble is slow to establish sessions.
  4. If the ensemble requires TLS or SASL, ensure the dialer and auth configuration match the server setup.

Example fix

// before
if err := waitForZooKeeperSession(ctx, events, timeout); err != nil {
    return err
}
// after
if err := waitForZooKeeperSession(ctx, events, timeout); err != nil {
    var netErr net.Error
    if errors.As(err, &netErr) { return fmt.Errorf("zk unreachable: %w", err) }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Reachability pre-check before dialing
conn, err := net.DialTimeout("tcp", "zk1:2181", 3*time.Second)
if err != nil { log.Fatal("ZooKeeper unreachable: ", err) }
conn.Close()

Try / catch

if err := waitForZooKeeperSession(ctx, events, timeout); err != nil {
    var transient interface{ Temporary() bool }
    if errors.As(err, &transient) && transient.Temporary() {
        return retryWithBackoff(ctx)
    }
    return fmt.Errorf("zk session setup failed: %w", err)
}

Prevention

When it happens

Trigger: waitForZooKeeperSession, called from Endpoints right after dialing, receives a zk.Event with Err set — i.e. the go-zk client reported a connection-level failure before reaching StateHasSession.

Common situations: ZooKeeper ensemble unreachable (firewall, wrong host list), TLS handshake failure against a SASL/SSL ensemble, ensemble quorum loss while connecting, or resolving to a dead server in the connection string.

Related errors


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