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

  1. Append a port to the address in the config, e.g. `addr: localhost:9090`
  2. Use `addr: :9090` to bind all interfaces on a port
  3. 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

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


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/ac9a7e42b00c3d6e. Report an issue: GitHub.