{"record":{"id":"a6a8c0211169ee66","repo":"gorilla/websocket","slug":"f-1-proxy-response-status-text","errorCode":null,"errorMessage":"f[1] (proxy response status text)","messagePattern":"f\\[1\\] \\(proxy response status text\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy.go","lineNumber":101,"sourceCode":"\tif err != nil {\n\t\tconn.Close()\n\t\treturn nil, err\n\t}\n\n\t// Close the response body to silence false positives from linters. Reset\n\t// the buffered reader first to ensure that Close() does not read from\n\t// conn.\n\t// Note: Applications must call resp.Body.Close() on a response returned\n\t// http.ReadResponse to inspect trailers or read another response from the\n\t// buffered reader. The call to resp.Body.Close() does not release\n\t// resources.\n\tbr.Reset(bytes.NewReader(nil))\n\t_ = resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\t_ = conn.Close()\n\t\tf := strings.SplitN(resp.Status, \" \", 2)\n\t\treturn nil, errors.New(f[1])\n\t}\n\treturn conn, nil\n}\n","sourceCodeStart":83,"sourceCodeEnd":105,"githubUrl":"https://github.com/gorilla/websocket/blob/e064f32e3674d9d79a8fd417b5bc06fa5c6cad8f/proxy.go#L83-L105","documentation":"This error is returned by DialContext when an HTTP proxy responds to the CONNECT request with a status code other than 200. The library closes the connection and surfaces the proxy's own status message (e.g. '407 Proxy Authentication Required' → 'Proxy Authentication Required') as the error text. It means the proxy refused to open the tunnel to the target host, not that the WebSocket handshake itself failed.","triggerScenarios":"dialer.Dial/DialContext called with Proxy set (http.ProxyFromEnvironment or custom) where the proxy answers the CONNECT with e.g. 407 (missing proxy credentials), 403 (target blocked by policy), 502/503 (proxy cannot reach target or is overloaded).","commonSituations":"Corporate environments where HTTPS_PROXY is set but credentials are missing from the proxy URL (user:pass@host) or the proxy requires NTLM/Kerberos auth gorilla does not support; VPN/network changes making the proxy unreachable to the target; proxy ACLs blocking the destination port 443/80.","solutions":["Check the status message in the error (it is the proxy's status text) to identify why the tunnel was refused","If it is a 407, embed credentials in the proxy URL, e.g. http://user:pass@proxy:8080, or configure them via HTTPS_PROXY, since gorilla only supports Basic proxy auth","Verify with curl -x $HTTPS_PROXY https://target-host that the proxy can reach the target; fix proxy ACLs/whitelisting if blocked","Confirm env vars (HTTPS_PROXY/HTTP_PROXY/NO_PROXY) point at the correct reachable proxy, or unset Proxy in the Dialer if no proxy is needed","Retry later or use a different proxy if the status is 502/503 (upstream outage)"],"exampleFix":"// before (407: proxy needs auth)\nu := websocket.Upgrader{}\n_, _, err := websocket.DefaultDialer.DialContext(ctx, \"wss://example.com/ws\", nil)\n// err: \"Proxy Authentication Required\"\n// after: supply Basic proxy credentials in the proxy URL\nproxyURL, _ := url.Parse(\"http://user:pass@proxy.corp:8080\")\ndialer := &websocket.Dialer{\n    Proxy: http.ProxyURL(proxyURL),\n    HandshakeTimeout: 10 * time.Second,\n}\nconn, _, err := dialer.DialContext(ctx, \"wss://example.com/ws\", nil)","handlingStrategy":"retry","validationCode":"proxyURL, err := http.ProxyFromEnvironment(&http.Request{URL: targetURL})\nif err != nil {\n    return nil, fmt.Errorf(\"bad proxy config: %w\", err)\n}\nif proxyURL != nil && proxyURL.User == nil && os.Getenv(\"HTTPS_PROXY\") != \"\" {\n    log.Printf(\"warning: proxy %s has no credentials; CONNECT may return 407\", proxyURL.Host)\n}","typeGuard":"func isProxyStatusError(err error) bool {\n    if err == nil {\n        return false\n    }\n    for _, code := range []int{403, 407, 502, 503} {\n        if strings.Contains(err.Error(), http.StatusText(code)) {\n            return true\n        }\n    }\n    return false\n}","tryCatchPattern":"conn, _, err := dialer.DialContext(ctx, wsURL, nil)\nif err != nil {\n    if isProxyStatusError(err) {\n        if strings.Contains(err.Error(), http.StatusText(407)) {\n            // fix proxy credentials, then retry once\n            dialer.Proxy = http.ProxyURL(proxyWithAuth)\n            conn, _, err = dialer.DialContext(ctx, wsURL, nil)\n        }\n        // 502/503: retry with backoff\n        if backoff := retryWithBackoff(ctx); backoff != nil {\n            conn, _, err = dialer.DialContext(ctx, wsURL, nil)\n        }\n    }\n    if err != nil {\n        return fmt.Errorf(\"ws dial failed: %w\", err)\n    }\n}","preventionTips":["Put credentials in the proxy URL (user:pass@host) before deploying behind a corporate proxy","Prefer http.ProxyFromEnvironment and keep HTTPS_PROXY/NO_PROXY correct per environment","Smoke-test the CONNECT path with curl -x $HTTPS_PROXY https://target in CI","Support only proxies that allow Basic auth, since gorilla has no NTLM/Kerberos support","Add a short HandshakeTimeout so proxy failures fail fast instead of hanging"],"tags":["network","proxy","websocket","dial","connect-tunnel"],"backgroundTag":"proxy-connect-failed","analyzedSha":"e064f32e3674d9d79a8fd417b5bc06fa5c6cad8f","analyzedAt":"2026-08-31T12:40:58.222Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}