benbjohnson/litestream · error
must specify port for bind address: %q
Error message
must specify port for bind address: %q
What it means
When the `addr` config option is set, Litestream serves Prometheus metrics over HTTP. The address must include a port; `net.SplitHostPort` returning an empty port means only a host was given. Run rejects it since there is no meaningful default metrics port.
Source
Thrown at cmd/litestream/replicate.go:355
slogWith.Info("replicating to", "bucket", client.Bucket, "path", client.Path)
case *abs.ReplicaClient:
slogWith.Info("replicating to", "bucket", client.Bucket, "path", client.Path, "endpoint", client.Endpoint)
case *sftp.ReplicaClient:
slogWith.Info("replicating to", "host", client.Host, "user", client.User, "path", client.Path)
case *nats.ReplicaClient:
slogWith.Info("replicating to", "bucket", client.BucketName, "url", client.URL)
case *oss.ReplicaClient:
slogWith.Info("replicating to", "bucket", client.Bucket, "path", client.Path, "region", client.Region)
default:
slogWith.Info("replicating to")
}
}
// Serve metrics over HTTP if enabled.
if c.Config.Addr != "" {
hostport := c.Config.Addr
if host, port, _ := net.SplitHostPort(c.Config.Addr); port == "" {
return fmt.Errorf("must specify port for bind address: %q", c.Config.Addr)
} else if host == "" {
hostport = net.JoinHostPort("localhost", port)
}
slog.Info("serving metrics on", "url", fmt.Sprintf("http://%s/metrics", hostport))
go func() {
http.Handle("/metrics", promhttp.Handler())
if err := http.ListenAndServe(c.Config.Addr, nil); err != nil {
slog.Error("cannot start metrics server", "error", err)
}
}()
}
// Parse exec commands args & start subprocess.
if c.Config.Exec != "" {
execArgs, err := shellwords.Parse(c.Config.Exec)
if err != nil {
return fmt.Errorf("cannot parse exec command: %w", err)View on GitHub (pinned to 4ed7a308f6)
Solutions
- Append a port to the address in the config, e.g. `addr: localhost:9090`
- Use `addr: :9090` to bind all interfaces on a port
- Remove the `addr` option entirely if metrics serving is not needed
Example fix
// before (litestream.yml) addr: localhost // after addr: localhost:9090
Defensive patterns
Strategy: validation
Validate before calling
# validate addr includes a port ADDR=$(yq '.addr' litestream.yml) if [ -n "$ADDR" ] && [[ "$ADDR" != *:* ]]; then echo "addr must include a port, e.g. $ADDR:9090" >&2; exit 1 fi
Prevention
- Always write addr as host:port or :port
- Add a config linter/CI check for the addr field
- Document the metrics port in deployment templates
When it happens
Trigger: Config sets `addr: localhost` or `addr: 0.0.0.0` (no `:port` suffix), so `port == ""` in Run's metrics-server setup at replicate.go:355.
Common situations: Users copying `addr:` host-only examples, assuming a default port exists, or editing config and dropping the `:9090` suffix.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- heartbeat URL must be a valid HTTP or HTTPS URL
- heartbeat interval must be at least 1 minute
- config file not found
- failed to read response: %w
- info failed: %s
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/ac9a7e42b00c3d6e.
Report an issue: GitHub.