nats-io/nats-server · error
proxy URL scheme must be http or https, got
Error message
proxy URL scheme must be http or https, got: %s
What it means
After a successful parse, validateLeafNodeProxyOptions requires the proxy URL scheme to be http or https; any other scheme (socks5, ftp, empty) is rejected with this error because the leaf node dialer only supports HTTP(S) CONNECT proxies. Thrown from validateLeafNode and parseRemoteLeafNodes during config validation.
Solutions
- Change the scheme to http:// or https:// for the proxy URL
- If only a SOCKS proxy is available, deploy an HTTP CONNECT proxy instead (leafnode proxy support is HTTP(S) only)
- Include the scheme explicitly, e.g. url: "http://proxy.corp:3128"
Example fix
// before
proxy { url: "socks5://proxy.corp:1080" }
// after
proxy { url: "http://proxy.corp:3128" } Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(cfg.LeafNodes.Proxy.URL)
if err == nil && u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("proxy scheme must be http(s), got %q", u.Scheme)
} Prevention
- Never copy SOCKS-style ALL_PROXY values into leafnode proxy config
- Explicitly write the http:// or https:// scheme
- Verify the proxy supports HTTP CONNECT before configuring it
When it happens
Trigger: remote leafnode proxy { url } parses fine but proxyURL.Scheme is not "http" or "https" — e.g. "socks5://proxy:1080", "tcp://...", or a URL with no scheme at all.
Common situations: Operators assuming SOCKS proxies are supported and writing socks5:// URLs; environments where an env var like ALL_PROXY (socks scheme) is copied into the config; URLs pasted without scheme defaulting to "".
Related errors
- invalid proxy URL
- can not have a single nkey and a users array
- can not have a single user/pass and a users array
- duplicate user detected in leafnode authorization
- invalid leafnode's minimum version
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/efff96fbd140d91c.
Report an issue: GitHub.
Appendix: source
Thrown at server/leafnode.go:404
users[u.Username] = struct{}{}
}
return nil
}
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
View on GitHub (pinned to 3a66a489d2)