{"record":{"id":"7926a980d71b7ec2","repo":"nats-io/nats-server","slug":"proxy-is-configured-but-remote-url-s-requires-tls","errorCode":null,"errorMessage":"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","messagePattern":"proxy is configured but remote URL (.+?) requires TLS and no TLS configuration is provided\\. When using proxy with TLS endpoints, ensure TLS is properly configured for the leafnode remote","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/leafnode.go","lineNumber":428,"sourceCode":"\n\tif remote.Proxy.Timeout < 0 {\n\t\treturn warnings, fmt.Errorf(\"proxy timeout must be >= 0\")\n\t}\n\n\tif (remote.Proxy.Username == _EMPTY_) != (remote.Proxy.Password == _EMPTY_) {\n\t\treturn warnings, fmt.Errorf(\"proxy username and password must both be specified or both be empty\")\n\t}\n\n\tif len(remote.URLs) > 0 {\n\t\thasWebSocketURL := false\n\t\thasNonWebSocketURL := false\n\n\t\tfor _, remoteURL := range remote.URLs {\n\t\t\tif remoteURL.Scheme == wsSchemePrefix || remoteURL.Scheme == wsSchemePrefixTLS {\n\t\t\t\thasWebSocketURL = true\n\t\t\t\tif (remoteURL.Scheme == wsSchemePrefixTLS) &&\n\t\t\t\t\tremote.TLSConfig == nil && !remote.TLS {\n\t\t\t\t\treturn 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())\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\thasNonWebSocketURL = true\n\t\t\t}\n\t\t}\n\n\t\tif !hasWebSocketURL {\n\t\t\twarnings = 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://)\")\n\t\t} else if hasNonWebSocketURL {\n\t\t\twarnings = append(warnings, \"proxy configuration will only be used for WebSocket URLs: proxy settings do not apply to TCP connections (nats://)\")\n\t\t}\n\t}\n\n\treturn warnings, nil\n}\n\n// Wait for the configured reconnect interval before attempting to connect\n// again to the remote leafnode.","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/leafnode.go#L410-L446","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nremotes [\n  { url: \"wss://leaf.example.com:443\"\n    proxy { url: \"http://proxy:3128\" } }\n]\n// after\nremotes [\n  { url: \"wss://leaf.example.com:443\"\n    tls { cert_file: \"./cert.pem\" key_file: \"./key.pem\" ca_file: \"./ca.pem\" }\n    proxy { url: \"http://proxy:3128\" } }\n]","handlingStrategy":"validation","validationCode":"for _, u := range remote.URLs {\n    if strings.HasPrefix(u.Scheme, \"wss\") && remote.Proxy != nil && remote.TLSConfig == nil && !remote.TLS {\n        return fmt.Errorf(\"wss:// remote %s with proxy needs TLS config\", u.String())\n    }\n}","typeGuard":"func tlsReadyForWssProxy(r *RemoteLeafOpts) bool {\n    return r.Proxy == nil || r.TLSConfig != nil || r.TLS\n}","tryCatchPattern":"if err := server.ProcessConfigFile(conf); err != nil {\n    log.Fatalf(\"config rejected (missing TLS for proxied wss remote?): %v\", err)\n}","preventionTips":["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"],"tags":["configuration","leafnode","proxy","tls","websocket"],"backgroundTag":"missing-tls-config","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}