{"record":{"id":"2365997f5ecc1a20","repo":"XTLS/Xray-core","slug":"proxy-responded-with-non-200-code-status","errorCode":null,"errorMessage":"Proxy responded with non 200 code: {status}","messagePattern":"Proxy responded with non 200 code: (.+?)","errorType":"http","errorClass":"errors.Error","httpStatus":null,"severity":"error","filePath":"proxy/http/client.go","lineNumber":243,"sourceCode":"\tconnectHTTP1 := func(rawConn net.Conn) (net.Conn, error) {\n\t\treq.Header.Set(\"Proxy-Connection\", \"Keep-Alive\")\n\n\t\terr := req.Write(rawConn)\n\t\tif err != nil {\n\t\t\trawConn.Close()\n\t\t\treturn nil, err\n\t\t}\n\n\t\tresp, err := http.ReadResponse(bufio.NewReader(rawConn), req)\n\t\tif err != nil {\n\t\t\trawConn.Close()\n\t\t\treturn nil, err\n\t\t}\n\t\tdefer resp.Body.Close()\n\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\trawConn.Close()\n\t\t\treturn nil, errors.New(\"Proxy responded with non 200 code: \" + resp.Status)\n\t\t}\n\t\treturn rawConn, nil\n\t}\n\n\tconnectHTTP2 := func(rawConn net.Conn, h2clientConn *http2.ClientConn) (net.Conn, error) {\n\t\tpr, pw := io.Pipe()\n\t\treq.Body = pr\n\n\t\tvar pErr error\n\t\tvar wg sync.WaitGroup\n\t\twg.Add(1)\n\n\t\tgo func() {\n\t\t\t_, pErr = pw.Write(firstPayload)\n\t\t\twg.Done()\n\t\t}()\n\n\t\tresp, err := h2clientConn.RoundTrip(req)","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/http/client.go#L225-L261","documentation":"HTTP/1.1 path of setUpHTTPTunnel: the proxy answered the CONNECT request, but the response status was not 200. The full status line (code + reason) is embedded in the message, so 407/403/502 are directly readable. The rawConn is closed and the error propagates to the retry loop.","triggerScenarios":"CONNECT to the configured HTTP proxy returns any non-200: 407 (proxy auth required / bad credentials), 403 (target not allowed by proxy policy), 502/503 (proxy cannot reach target), 451, etc.","commonSituations":"Wrong user/pass in settings.servers[].users, proxy allowlists blocking the client IP or destination port, corporate proxies restricting CONNECT to 443 only, captive portals intercepting with 302/403.","solutions":["Read the status in the message: 407 → fix credentials; 403 → adjust proxy ACL for the target/port; 502 → target unreachable from proxy","If the proxy only allows CONNECT 443, restrict targets or switch outbound type","Verify with curl: `curl -x http://proxy:3128 -p https://target -v` and compare status lines","Handle captive-portal/proxy-auth environments before routing traffic"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"```go\n// manual CONNECT probe\nreq, _ := http.NewRequest(http.MethodConnect, targetAddr, nil)\nresp, err := http.DefaultTransport.(*http.Transport).RoundTrip(req)\nif err == nil && resp.StatusCode != 200 { /* fix auth/ACL before deploy */ }\n```","typeGuard":null,"tryCatchPattern":"```go\nif err := c.Process(ctx, link, dialer); err != nil {\n    if strings.Contains(err.Error(), \"non 200 code\") {\n        status := extractStatus(err) // 407 auth, 403 policy, 502 upstream\n        // map to config fix; do not retry auth failures\n    }\n}\n```","preventionTips":["curl-verify proxy auth and ACLs","Allowlist Xray host on the proxy","Restrict CONNECT targets to ports the proxy permits"],"tags":["http-outbound","connect","status-code","proxy","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}