nats-io/nats-server · error

could not parse port %q

Error message

could not parse port %q

What it means

This error is raised by the address-parsing helper in server/opts.go when the host portion split off by net.SplitHostPort is not a valid integer. The port substring exists but strconv.Atoi rejects it, so the library returns this error instead of proceeding with an unusable port.

Source

Thrown at server/opts.go:2008

	host string
	port int
}

// parseListen will parse listen option which is replacing host/net and port
func parseListen(v any) (*hostPort, error) {
	hp := &hostPort{}
	switch vv := v.(type) {
	// Only a port
	case int64:
		hp.port = int(vv)
	case string:
		host, port, err := net.SplitHostPort(vv)
		if err != nil {
			return nil, fmt.Errorf("could not parse address string %q", vv)
		}
		hp.port, err = strconv.Atoi(port)
		if err != nil {
			return nil, fmt.Errorf("could not parse port %q", port)
		}
		hp.host = host
	default:
		return nil, fmt.Errorf("expected port or host:port, got %T", vv)
	}
	return hp, nil
}

// parseCluster will parse the cluster config.
func parseCluster(v any, opts *Options, errors *[]error, warnings *[]error) error {
	var lt token
	defer convertPanicToErrorList(&lt, errors)

	tk, v := unwrapValue(v, &lt)
	cm, ok := v.(map[string]any)
	if !ok {
		return &configErr{tk, fmt.Sprintf("Expected map to define cluster, got %T", v)}
	}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Set the port to a plain decimal integer within 1–65535, e.g. '0.0.0.0:4222'.
  2. Check env interpolation: ensure ${PORT} is actually set and numeric in the server's environment.
  3. Strip any protocol suffix or whitespace from the port portion.
  4. Use the offending %q value from the error to see exactly what Atoi received.

Example fix

// before
listen: 0.0.0.0:${PORT}  # PORT unset
// after
listen: 0.0.0.0:4222
Defensive patterns

Strategy: validation

Validate before calling

_, port, err := net.SplitHostPort(addr)
if err != nil {
	return err
}
if n, aerr := strconv.Atoi(port); aerr != nil || n < 1 || n > 65535 {
	return fmt.Errorf("invalid port %q in %q", port, addr)
}

Prevention

When it happens

Trigger: Config address strings like 'host:4222x', 'host:-1', or 'host: 4222' (embedded space) where SplitHostPort succeeds but Atoi fails on the port part.

Common situations: Typos in the port number; units accidentally included ('host:4222/tcp'); env interpolation producing an empty or non-numeric port ('host:${PORT}' with PORT unset); negative or oversized values.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/03ae1f753c99a883. Report an issue: GitHub.