{"record":{"id":"0bc273f36e8ac3b3","repo":"t8y2/dbx","slug":"zookeeper-connection-event-w","errorCode":null,"errorMessage":"ZooKeeper connection event: %w","messagePattern":"ZooKeeper connection event: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/argo-go/discovery.go","lineNumber":204,"sourceCode":"\t}\n\treturn \"/\" + strings.Join(cleaned, \"/\")\n}\n\nfunc waitForZooKeeperSession(ctx context.Context, events <-chan zk.Event, timeout time.Duration) error {\n\ttimer := time.NewTimer(timeout)\n\tdefer timer.Stop()\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-timer.C:\n\t\t\treturn errors.New(\"ZooKeeper connection timed out before a session was established\")\n\t\tcase event, ok := <-events:\n\t\t\tif !ok {\n\t\t\t\treturn errors.New(\"ZooKeeper event stream closed before a session was established\")\n\t\t\t}\n\t\t\tif event.Err != nil {\n\t\t\t\treturn fmt.Errorf(\"ZooKeeper connection event: %w\", event.Err)\n\t\t\t}\n\t\t\tswitch event.State {\n\t\t\tcase zk.StateHasSession:\n\t\t\t\treturn nil\n\t\t\tcase zk.StateAuthFailed:\n\t\t\t\treturn errors.New(\"ZooKeeper authentication failed\")\n\t\t\tcase zk.StateExpired:\n\t\t\t\treturn errors.New(\"ZooKeeper session expired during connection\")\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc parseHiveServerRegistration(child string, data []byte) (endpoint, error) {\n\tcandidates := []string{strings.TrimSpace(string(data)), strings.TrimSpace(child)}\n\tfor _, candidate := range candidates {\n\t\tif candidate == \"\" {\n\t\t\tcontinue","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/argo-go/discovery.go#L186-L222","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the wrapped error: if it is a dial error, verify the zooKeeper server list and network reachability (telnet/nc to host:2181).","If TLS is configured, confirm the ensemble actually serves TLS and certificates/CA/ServerName are correct; remove zooKeeperTLSConfig for plaintext ensembles.","Increase connectTimeout if the error indicates a timeout rather than refusal.","Retry Endpoints() with backoff — ZK event errors during transient ensemble hiccups are often temporary."],"exampleFix":"// before\ntlsConfig := &tls.Config{...} // against plaintext ZK\n// after\nserviceDiscoveryMode=zookeeper, zooKeeperTLSConfig unset  // plaintext ensemble","handlingStrategy":"retry","validationCode":"// preflight: TCP reachability of every ZK server\nfor _, addr := range zkAddresses {\n    conn, err := net.DialTimeout(\"tcp\", addr, 3*time.Second)\n    if err != nil { return fmt.Errorf(\"ZooKeeper %s unreachable: %w\", addr, err) }\n    conn.Close()\n}","typeGuard":null,"tryCatchPattern":"err := waitForZooKeeperSession(ctx, events, timeout)\nif err != nil {\n    var zkErr error\n    if errors.As(err, &zkErr) && strings.HasPrefix(err.Error(), \"ZooKeeper connection event\") {\n        return retryWithBackoff(3) // transient handshake failure\n    }\n    return err\n}","preventionTips":["Verify ZK host/port list and firewall rules before enabling zookeeper discovery mode.","Only set zooKeeperTLSConfig for ensembles that actually serve TLS.","Keep timeouts generous enough for cross-DC ensembles.","Retry with backoff — event errors during ensemble hiccups are often transient."],"tags":["zookeeper","network","tls","go"],"backgroundTag":"zookeeper-connection-error","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}