{"record":{"id":"006a43af6e6d3967","repo":"nats-io/nats-server","slug":"unexpected-proxy-url-parse-error-url-was-pre-vali","errorCode":null,"errorMessage":"unexpected proxy URL parse error (URL was pre-validated): %v","messagePattern":"unexpected proxy URL parse error \\(URL was pre-validated\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/leafnode.go","lineNumber":626,"sourceCode":"\t}\n\ts.leafNodeOpts.resolver = opts.LeafNode.resolver\n\tif s.leafNodeOpts.resolver == nil {\n\t\ts.leafNodeOpts.resolver = net.DefaultResolver\n\t}\n\ts.leafNodeOpts.dialer = opts.LeafNode.dialer\n\tif s.leafNodeOpts.dialer == nil {\n\t\ts.leafNodeOpts.dialer = natsDialTimeout\n\t}\n}\n\nconst sharedSysAccDelay = 250 * time.Millisecond\n\n// establishHTTPProxyTunnel establishes an HTTP CONNECT tunnel through a proxy server\nfunc establishHTTPProxyTunnel(proxyURL, targetHost string, timeout time.Duration, username, password string) (net.Conn, error) {\n\tproxyAddr, err := url.Parse(proxyURL)\n\tif err != nil {\n\t\t// This should not happen since proxy URL is validated during configuration parsing\n\t\treturn nil, fmt.Errorf(\"unexpected proxy URL parse error (URL was pre-validated): %v\", err)\n\t}\n\n\t// Connect to the proxy server\n\tconn, err := natsDialTimeout(\"tcp\", proxyAddr.Host, timeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to connect to proxy: %v\", err)\n\t}\n\n\t// Set deadline for the entire proxy handshake\n\tif err := conn.SetDeadline(time.Now().Add(timeout)); err != nil {\n\t\tconn.Close()\n\t\treturn nil, fmt.Errorf(\"failed to set deadline: %v\", err)\n\t}\n\n\treq := &http.Request{\n\t\tMethod: http.MethodConnect,\n\t\tURL:    &url.URL{Opaque: targetHost}, // Opaque is required for CONNECT\n\t\tHost:   targetHost,","sourceCodeStart":608,"sourceCodeEnd":644,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/leafnode.go#L608-L644","documentation":"establishHTTPProxyTunnel failed to re-parse the proxy URL string that was already validated during configuration. This is a defensive/unexpected path — by the time the tunnel is established the URL passed validation, so url.Parse should never fail. Hitting it indicates an internal inconsistency (URL mutated between validation and dial) rather than a user config problem.","triggerScenarios":"url.Parse(proxyURL) returning an error inside establishHTTPProxyTunnel despite pre-validation in validateLeafNodeProxyOptions — practically only if the stored proxy URL string is corrupt or modified after parsing.","commonSituations":"Bugs in code that rewrites the proxy URL between config validation and connection; custom test harnesses calling establishHTTPProxyTunnel with an unvalidated string.","solutions":["Check whether any code mutates the remote's Proxy URL after validation","Call establishHTTPProxyTunnel only with URLs that passed validateLeafNodeProxyOptions","If reproducible with stock config, report as a bug with the exact proxy URL value"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if _, err := url.Parse(proxyURL); err != nil {\n    return fmt.Errorf(\"proxy URL invalid before tunnel: %w\", err)\n}","typeGuard":"func parseableProxyURL(raw string) bool {\n    _, err := url.Parse(raw)\n    return err == nil\n}","tryCatchPattern":"conn, err := establishHTTPProxyTunnel(purl, host, timeout, user, pass)\nif err != nil {\n    if strings.Contains(err.Error(), \"unexpected proxy URL parse error\") {\n        log.Fatalf(\"BUG: proxy URL mutated after validation: %v\", err)\n    }\n    return err\n}","preventionTips":["Treat this as an internal bug and file it if seen with stock config","Never mutate RemoteLeafOpts Proxy URL after config parsing","Only call establishHTTPProxyTunnel with pre-validated URLs"],"tags":["proxy","internal","url","defensive"],"backgroundTag":"unexpected-parse-error","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}