nats-io/nats-server · error
proxy is configured but remote URL %s requires TLS and no TL
Error message
proxy is configured but remote URL %s requires TLS and no TLS configuration is provided. When using proxy with TLS endpoints, ensure TLS is properly configured for the leafnode remote
What it means
A proxy is configured for a leafnode remote whose URL uses the secure websocket scheme (wss://), but the remote has no TLS configuration (TLSConfig nil and TLS flag false). The CONNECT tunnel through the proxy carries the TLS handshake to the endpoint, so the client side must have TLS enabled to speak wss through it; the server refuses this inconsistent combination at validation time.
Source
Thrown at server/leafnode.go:428
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) &&
remote.TLSConfig == nil && !remote.TLS {
return warnings, fmt.Errorf("proxy is configured but remote URL %s requires TLS and no TLS configuration is provided. When using proxy with TLS endpoints, ensure TLS is properly configured for the leafnode remote", remoteURL.String())
}
} else {
hasNonWebSocketURL = true
}
}
if !hasWebSocketURL {
warnings = append(warnings, "proxy configuration will be ignored: proxy settings only apply to WebSocket connections (ws:// or wss://), but all configured URLs use TCP connections (nats://)")
} else if hasNonWebSocketURL {
warnings = append(warnings, "proxy configuration will only be used for WebSocket URLs: proxy settings do not apply to TCP connections (nats://)")
}
}
return warnings, nil
}
// Wait for the configured reconnect interval before attempting to connect
// again to the remote leafnode.View on GitHub (pinned to 3a66a489d2)
Solutions
- Add a tls block (or TLSConfig) to the leafnode remote so wss:// can be negotiated
- If TLS is not actually wanted, change the remote URL scheme to ws://
- Ensure the TLS block certificates are valid so the remote handshake succeeds
Example fix
// before
remotes [
{ url: "wss://leaf.example.com:443"
proxy { url: "http://proxy:3128" } }
]
// after
remotes [
{ url: "wss://leaf.example.com:443"
tls { cert_file: "./cert.pem" key_file: "./key.pem" ca_file: "./ca.pem" }
proxy { url: "http://proxy:3128" } }
] Defensive patterns
Strategy: validation
Validate before calling
for _, u := range remote.URLs {
if strings.HasPrefix(u.Scheme, "wss") && remote.Proxy != nil && remote.TLSConfig == nil && !remote.TLS {
return fmt.Errorf("wss:// remote %s with proxy needs TLS config", u.String())
}
} Type guard
func tlsReadyForWssProxy(r *RemoteLeafOpts) bool {
return r.Proxy == nil || r.TLSConfig != nil || r.TLS
} Try / catch
if err := server.ProcessConfigFile(conf); err != nil {
log.Fatalf("config rejected (missing TLS for proxied wss remote?): %v", err)
} Prevention
- Whenever a remote URL switches ws->wss, add/verify the tls block
- Remember proxy tunnels do not provide TLS themselves — the endpoint does
- Test leafnode connection to the wss endpoint in staging behind the proxy
When it happens
Trigger: remote.URLs contains a wss:// URL, remote.Proxy is set, remote.TLSConfig is nil and remote.TLS is false — caught in validateLeafNodeProxyOptions during validateLeafNode or parseRemoteLeafNodes.
Common situations: Switching a remote leafnode URL from ws:// to wss:// (e.g. behind a NATS WebSocket gateway) but forgetting to add the tls block; proxy added later without revisiting TLS; config where TLS was assumed inherited but the remote struct has none.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- proxy URL must specify a host
- proxy timeout must be >= 0
- proxy username and password must both be specified or both b
- 'cert_file' and 'cert_store' may not both be configured
- expected 'cert_store' to be a valid non-empty string
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/7926a980d71b7ec2.
Report an issue: GitHub.