{"record":{"id":"cf5d7c8b4f235307","repo":"t8y2/dbx","slug":"zookeeper-connect-string-contains-no-servers","errorCode":null,"errorMessage":"ZooKeeper connect string contains no servers","messagePattern":"ZooKeeper connect string contains no servers","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/zookeeper/connection.go","lineNumber":376,"sourceCode":"\nfunc parseConnectTarget(value string) (connectTarget, error) {\n\tconnectString := strings.TrimSpace(strings.TrimPrefix(value, \"zookeeper://\"))\n\tslash := strings.Index(connectString, \"/\")\n\thostsPart := connectString\n\tchroot := \"\"\n\tif slash >= 0 {\n\t\thostsPart = connectString[:slash]\n\t\tchroot = normalizePrefix(connectString[slash:])\n\t}\n\tservers := make([]string, 0)\n\tfor _, item := range strings.Split(hostsPart, \",\") {\n\t\tserver := strings.TrimSpace(item)\n\t\tif server != \"\" {\n\t\t\tservers = append(servers, server)\n\t\t}\n\t}\n\tif len(servers) == 0 {\n\t\treturn connectTarget{}, errors.New(\"ZooKeeper connect string contains no servers\")\n\t}\n\treturn connectTarget{Servers: servers, Chroot: chroot}, nil\n}\n\nfunc requireReachableServer(servers []string, timeout time.Duration) error {\n\tctx, cancel := context.WithTimeout(context.Background(), timeout+500*time.Millisecond)\n\tdefer cancel()\n\tworkers := minInt(len(servers), maximumReachabilityWorkers)\n\tjobs := make(chan string)\n\treachable := make(chan struct{}, 1)\n\tvar waitGroup sync.WaitGroup\n\tfor worker := 0; worker < workers; worker++ {\n\t\twaitGroup.Add(1)\n\t\tgo func() {\n\t\t\tdefer waitGroup.Done()\n\t\t\tfor server := range jobs {\n\t\t\t\taddress, err := endpointAddress(server)\n\t\t\t\tif err != nil {","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/zookeeper/connection.go#L358-L394","documentation":"parseConnectTarget splits the ZooKeeper connect string on commas into host:port server entries (with an optional chroot path). If, after trimming, no server entries remain, it returns 'ZooKeeper connect string contains no servers'.","triggerScenarios":"Calling openClient, TestConnectionConfiguration, or databaseInfo with a connect string that is empty, whitespace-only, consists only of separators, or is just a chroot path with no host:port entries before it. Raised in agents/drivers/zookeeper/connection.go:376.","commonSituations":"Config env var or YAML key missing/empty so the connect string is \"\"; a typo leaving only \"/chroot\" in the field; template/secret expansion yielding whitespace; trailing commas producing zero non-empty items.","solutions":["Set the connect string to at least one host:port, e.g. \"zk1:2181,zk2:2181\" (optionally with chroot: \"zk1:2181/app/ns\").","Check the config source (env var, config file, secret) is actually populated at runtime — log or print the resolved value.","Fix templating/escaping issues that dropped the server list.","Validate the config early with TestConnectionConfiguration before opening the client."],"exampleFix":"// before\nconfig.ConnectString = \"\"\n// after\nconfig.ConnectString = \"zk1:2181,zk2:2181\"","handlingStrategy":"validation","validationCode":"func validateConnectString(s string) error {\n    if strings.TrimSpace(s) == \"\" { return errors.New(\"zookeeper connect string is empty\") }\n    for _, item := range strings.Split(s, \",\") {\n        item = strings.TrimSpace(item)\n        if item != \"\" && strings.Contains(item, \":\") { return nil }\n    }\n    return errors.New(\"zookeeper connect string has no host:port servers\")\n}\n// call before openClient / TestConnectionConfiguration","typeGuard":null,"tryCatchPattern":"if err := validateConnectString(cfg.ConnectString); err != nil {\n    return fmt.Errorf(\"bad zookeeper config: %w\", err)\n}\nsession, err := openClient(cfg)\nif err != nil { return err }","preventionTips":["Fail fast at config load time if the connect string is empty","Log the resolved connect string (redacted) during startup","Avoid templated config that can expand to whitespace","Include a chroot only after valid host:port entries"],"tags":["configuration","zookeeper","connect-string","validation"],"backgroundTag":"invalid-connection-string","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}