{"record":{"id":"13569ffd9a3c878c","repo":"gastownhall/beads","slug":"addr-q-must-be-host-port-with-a-numeric-ip-lite","errorCode":null,"errorMessage":"--addr %q must be HOST:PORT with a numeric IP literal host (unix sockets are not supported): %w","messagePattern":"--addr %q must be HOST:PORT with a numeric IP literal host \\(unix sockets are not supported\\): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/httpapi/server.go","lineNumber":441,"sourceCode":"\t// edge-triggered rather than once per connection.\n\tmaxConns      int\n\tliveConns     atomic.Int64\n\tconnCapWarned atomic.Bool\n}\n\n// ValidateBindAddr enforces the bind posture, following the policy the managed\n// Dolt child already lives under (validateManagedServerConfigPolicy in\n// cmd/bd/proxied_server.go): the host must be a NUMERIC IP literal.\n//\n// Hostnames are refused, \"localhost\" included. A name is not a listener\n// specification — it resolves to whatever the host's resolver says today, so\n// the operator cannot tell from the flag which interfaces they just opened.\n// Unix sockets are not supported at all; they fail here because they do not\n// parse as host:port.\nfunc ValidateBindAddr(addr string, allowNonLoopback bool) (net.IP, error) {\n\thost, port, err := net.SplitHostPort(addr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"--addr %q must be HOST:PORT with a numeric IP literal host (unix sockets are not supported): %w\", addr, err)\n\t}\n\tif _, err := strconv.ParseUint(port, 10, 16); err != nil {\n\t\treturn nil, fmt.Errorf(\"--addr %q: port must be a number from 0 to 65535 (0 picks an ephemeral port)\", addr)\n\t}\n\tip := net.ParseIP(host)\n\tif ip == nil {\n\t\treturn nil, fmt.Errorf(\"--addr %q: host must be a numeric IP literal, not a name — use 127.0.0.1 rather than localhost\", addr)\n\t}\n\tif !ip.IsLoopback() && !allowNonLoopback {\n\t\treturn nil, fmt.Errorf(\"--addr %q binds beyond loopback, which requires --allow-non-loopback (and, with it, --auth-token-file)\", addr)\n\t}\n\treturn ip, nil\n}\n\n// Listen validates the configuration, binds the listener, and reports the\n// bound address on stdout and the startup state on stderr. It does not accept\n// anything until Serve runs.\n//","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/httpapi/server.go#L423-L459","documentation":"ValidateBindAddr parses the --addr flag and requires the form HOST:PORT where HOST is a numeric IP literal. If net.SplitHostPort fails — because the value is a unix socket path, a bare port, a hostname without port, or malformed bracket syntax — this error is returned. The server deliberately does not support unix sockets.","triggerScenarios":"Passing --addr values like \"/tmp/bd.sock\" (unix socket path), \"127.0.0.1\" (no port), \"://\", \"[::1]\" (missing port), or any string that is not host:port to server startup.","commonSituations":"Operators copying unix-socket configs from other tools (e.g. Docker-style -v socket setups); forgetting the port; pasting a hostname like \"localhost:8080\" where only a numeric IP is accepted downstream (this specific error fires on the SplitHostPort step); shell quoting stripping a colon.","solutions":["Use a numeric IP literal with an explicit port, e.g. --addr 127.0.0.1:8080.","Remove any unix socket path — unix sockets are unsupported; use TCP loopback instead.","Check for missing separators: the value must contain exactly one host:port (use [::1]:8080 for IPv6).","Inspect the wrapped error (%w) — SplitHostPort's message (missing port, too many colons) names the exact malformation."],"exampleFix":"// before\n--addr /var/run/bd.sock\n// after\n--addr 127.0.0.1:8080","handlingStrategy":"validation","validationCode":"// run before launching the server\nif _, err := net.SplitHostPort(addr); err != nil {\n    return fmt.Errorf(\"--addr must be HOST:PORT with a numeric IP, got %q\", addr)\n}\nhost, _, _ := net.SplitHostPort(addr)\nif net.ParseIP(host) == nil {\n    return fmt.Errorf(\"--addr host %q must be a numeric IP literal\", host)\n}","typeGuard":null,"tryCatchPattern":"ip, err := httpapi.ValidateBindAddr(addr, allowNonLoopback)\nif err != nil {\n    // actionable flag error: print usage hint and exit\n    fmt.Fprintf(os.Stderr, \"invalid --addr: %v\\n\", err)\n    os.Exit(2)\n}","preventionTips":["Always pass numeric IP literals: 127.0.0.1:<port> for loopback, 0.0.0.0:<port> for all interfaces.","Never use unix socket paths — the server does not support them.","For IPv6 use bracket syntax with port: [::1]:8080.","Validate the flag with ValidateBindAddr in scripts before starting the server."],"tags":["configuration","cli-flag","network","bind-address"],"backgroundTag":"invalid-bind-address","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}