{"record":{"id":"6631c9f1fecdc959","repo":"gastownhall/beads","slug":"addr-q-port-must-be-a-number-from-0-to-65535","errorCode":null,"errorMessage":"--addr %q: port must be a number from 0 to 65535 (0 picks an ephemeral port)","messagePattern":"--addr %q: port must be a number from 0 to 65535 \\(0 picks an ephemeral port\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/httpapi/server.go","lineNumber":444,"sourceCode":"\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//\n// There is no lock file, pid file or discovery file: bd serve is\n// operator-invoked and the TCP bind IS the mutual exclusion, so a second\n// instance on the same fixed port fails here with the operating system's own","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/httpapi/server.go#L426-L462","documentation":"ValidateBindAddr parses a --addr value as HOST:PORT with a numeric IP host. This error is thrown when the port portion is not a valid unsigned integer in the uint16 range (0-65535). Port 0 is explicitly allowed and picks an ephemeral port.","triggerScenarios":"Calling ValidateBindAddr (or starting the httpapi server) with an addr whose port fails strconv.ParseUint(port, 10, 16): non-numeric port like '127.0.0.1:http' or '127.0.0.1:abc', a service name instead of a number, or a value with surrounding characters like '127.0.0.1:8080 ' or sign/plus prefixes.","commonSituations":"Operator pastes a URL-form address (127.0.0.1:8080/ with path junk), uses a named service port ('http'), includes stray whitespace or quotes from a config file, or typos the port digits.","solutions":["Use a numeric port between 0 and 65535, e.g. --addr 127.0.0.1:8080 (0 for ephemeral)","Strip whitespace/quotes/paths from the addr value before passing it","Look up the numeric port behind any service name and use the number instead"],"exampleFix":"// before\nsrv, err := httpapi.Listen(cfg with Addr: \"127.0.0.1:http\")\n// after\nsrv, err := httpapi.Listen(cfg with Addr: \"127.0.0.1:80\")","handlingStrategy":"validation","validationCode":"func validPort(addr string) bool {\n    _, port, err := net.SplitHostPort(addr)\n    if err != nil { return false }\n    n, err := strconv.ParseUint(port, 10, 16)\n    return err == nil && n <= 65535\n}","typeGuard":null,"tryCatchPattern":"if err := validateAddr(addr); err != nil {\n    var ve *strconv.NumError\n    if errors.As(err, &ve) { /* handle bad port */ }\n}","preventionTips":["Always use numeric ports, never service names","Use port 0 when any free port is acceptable","Trim config/env values before passing to --addr"],"tags":["validation","cli","network","address-parsing"],"backgroundTag":"invalid-bind-address","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}