nats-io/nats-server · error
proxy URL must specify a host
Error message
proxy URL must specify a host
What it means
NATS server rejects a leafnode remote proxy URL that has no host component. When a proxy is configured via remote.Proxy.URL, the URL must point at an actual proxy host; a scheme-only URL like 'http://' carries no routing information and cannot be dialed. validateLeafNodeProxyOptions fails fast at config parse time so the server never starts with an unusable proxy.
Source
Thrown at server/leafnode.go:408
func validateLeafNodeProxyOptions(remote *RemoteLeafOpts) ([]string, error) {
var warnings []string
if remote.Proxy.URL == _EMPTY_ {
return warnings, nil
}
proxyURL, err := url.Parse(remote.Proxy.URL)
if err != nil {
return warnings, fmt.Errorf("invalid proxy URL: %v", err)
}
if proxyURL.Scheme != "http" && proxyURL.Scheme != "https" {
return warnings, fmt.Errorf("proxy URL scheme must be http or https, got: %s", proxyURL.Scheme)
}
if proxyURL.Host == _EMPTY_ {
return warnings, fmt.Errorf("proxy URL must specify a host")
}
if remote.Proxy.Timeout < 0 {
return warnings, fmt.Errorf("proxy timeout must be >= 0")
}
if (remote.Proxy.Username == _EMPTY_) != (remote.Proxy.Password == _EMPTY_) {
return warnings, fmt.Errorf("proxy username and password must both be specified or both be empty")
}
if len(remote.URLs) > 0 {
hasWebSocketURL := false
hasNonWebSocketURL := false
for _, remoteURL := range remote.URLs {
if remoteURL.Scheme == wsSchemePrefix || remoteURL.Scheme == wsSchemePrefixTLS {
hasWebSocketURL = true
if (remoteURL.Scheme == wsSchemePrefixTLS) &&View on GitHub (pinned to 3a66a489d2)
Solutions
- Set a full proxy URL including host and port, e.g. proxy_url: "http://proxy.internal:3128"
- Check that any env-expanded variable in the proxy URL is non-empty before starting the server
- Validate the URL with url.Parse and check u.Host != "" in your deployment tooling
Example fix
// before proxy_url: "http://" // after proxy_url: "http://proxy.internal:3128"
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(proxyURLString)
if err != nil || u.Scheme != "http" && u.Scheme != "https" || u.Host == "" {
return fmt.Errorf("proxy URL must be http(s) with a host, got %q", proxyURLString)
} Type guard
func hasProxyHost(raw string) bool {
u, err := url.Parse(raw)
return err == nil && u.Host != ""
} Try / catch
if err := server.CheckLeafNodeProxy(cfg); err != nil {
log.Fatalf("invalid proxy config: %v", err)
} Prevention
- Always include host:port in proxy_url
- Lint nats.conf for empty interpolated variables before deploy
- Validate config with nats-server --config ... -t (config test) before restart
When it happens
Trigger: Setting a leafnode remote proxy URL to a value without a host, e.g. proxy_url: "http://" or "https://" in the leafnodes remotes config, or constructing url.URL{Scheme: "http"} with empty Host in code before parseRemoteLeafNodes/validateLeafNode runs.
Common situations: Config templating that leaves the proxy host variable empty (unset env var interpolated to nothing); hand-edited nats.conf dropping the host after the scheme; copy-paste of a proxy option block without filling in the address.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- proxy timeout must be >= 0
- proxy username and password must both be specified or both b
- proxy is configured but remote URL %s requires TLS and no TL
- attempted to connect to leaf node port
- remote leafnode has same cluster name
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/fa67b464f2b2cff1.
Report an issue: GitHub.