{"record":{"id":"1bdbab989ded0dda","repo":"t8y2/dbx","slug":"zookeeper-event-stream-closed-before-a-session-was-1bdbab","errorCode":null,"errorMessage":"ZooKeeper event stream closed before a session was established","messagePattern":"ZooKeeper event stream closed before a session was established","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/hive-go/discovery.go","lineNumber":201,"sourceCode":"\t}\n\tif len(cleaned) == 0 {\n\t\treturn \"/\"\n\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)}","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/hive-go/discovery.go#L183-L219","documentation":"The ZooKeeper client's event channel was closed before any session event arrived, so waitForZooKeeperSession cannot observe connection state and stops with this error. It indicates the underlying zk connection was shut down or the driver closed the event stream unexpectedly.","triggerScenarios":"Calling Endpoints when the zk.Conn is closed concurrently (Close called, or the client tears down after a fatal error) while the session wait is still consuming events.","commonSituations":"Parent context cancelation code path that closes the connection but not the events channel, double-Close of the discovery, or an older go-zk version closing the channel after connection errors.","solutions":["Ensure the ZooKeeper connection is not closed while Endpoints is running (check for early defer Close or double Close)","Inspect for fatal client errors preceding the channel close and surface them","Upgrade/verify the go-zk dependency for known channel-close behavior changes","Serialize Endpoints calls so concurrent invocations don't tear down a shared connection"],"exampleFix":"// before\ngo func() { connection.Close() }() // closes while Endpoints waits\nconnection, events, _ := zk.Connect(...)\n// after\nconnection, events, _ := zk.Connect(...)\ndefer connection.Close() // close only after Endpoints returns","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"endpoints, err := discovery.Endpoints(ctx)\nif err != nil && strings.Contains(err.Error(), \"event stream closed\") {\n    // recreate the zk connection and retry once\n    return recreateConnectionAndDiscover(ctx)\n}","preventionTips":["Never close the zk.Conn while Endpoints is in flight; use defer after all use","Guard against concurrent Endpoints calls on a shared connection","Check the go-zk version for known event-channel close semantics"],"tags":["zookeeper","connection","lifecycle","concurrency"],"backgroundTag":"connection-closed-unexpectedly","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"}