{"record":{"id":"0bef2fc30a6d5172","repo":"xai-org/grok-build","slug":"failed-to-connect-to-proxy-at-proxy-addr-e","errorCode":null,"errorMessage":"Failed to connect to proxy at {proxy_addr}: {e}","messagePattern":"Failed to connect to proxy at (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell/src/agent/proxy.rs","lineNumber":151,"sourceCode":"/// 1. Parse the proxy URL to get host + port.\n/// 2. Open a plain TCP connection to the proxy.\n/// 3. Send `CONNECT target_host:target_port HTTP/1.1\\r\\n\\r\\n`.\n/// 4. Read the proxy's response; expect `HTTP/1.x 200 …`.\n/// 5. Return the raw `TcpStream` positioned after the CONNECT response.\nasync fn open_connect_tunnel(\n    proxy_url: &str,\n    target_host: &str,\n    target_port: u16,\n) -> anyhow::Result<TcpStream> {\n    // 1. Parse proxy URL.\n    let (proxy_host, proxy_port) = parse_proxy_url(proxy_url)?;\n\n    // 2. TCP connect to proxy.\n    let proxy_addr = format!(\"{proxy_host}:{proxy_port}\");\n    debug!(proxy_addr = %proxy_addr, \"Opening TCP to proxy\");\n    let stream = TcpStream::connect(&proxy_addr)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to connect to proxy at {proxy_addr}: {e}\"))?;\n\n    // 3. Send HTTP CONNECT.\n    let connect_req = format!(\n        \"CONNECT {target_host}:{target_port} HTTP/1.1\\r\\n\\\n         Host: {target_host}:{target_port}\\r\\n\\\n         \\r\\n\"\n    );\n    let (reader_half, mut writer_half) = stream.into_split();\n    writer_half.write_all(connect_req.as_bytes()).await?;\n    writer_half.flush().await?;\n\n    // 4. Read the status line from the proxy.\n    let mut reader = BufReader::new(reader_half);\n    let mut status_line = String::new();\n    reader.read_line(&mut status_line).await?;\n    debug!(status_line = %status_line.trim(), \"Proxy CONNECT response\");\n\n    if !status_line.starts_with(\"HTTP/1.1 200\") && !status_line.starts_with(\"HTTP/1.0 200\") {","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/agent/proxy.rs#L133-L169","documentation":"`open_connect_tunnel` throws this when the plain TCP connection to the HTTP CONNECT proxy itself fails (`TcpStream::connect(&proxy_addr)` returns an OS-level error). Before any CONNECT request is sent, the library must establish a TCP socket to the proxy host:port parsed from the proxy URL; if that socket setup fails, the underlying io error (refused, unreachable, DNS failure, timeout) is wrapped in this message. It indicates a problem reaching the proxy, not the target host.","triggerScenarios":"Calling `connect_via_proxy` (directly or via WebSocket connect when HTTPS_PROXY/HTTP_PROXY is set) where the proxy host is unreachable: nothing is listening on the proxy port, wrong proxy URL in the environment, DNS cannot resolve the proxy hostname, a firewall drops packets, or the proxy port in `HTTPS_PROXY`/`HTTP_PROXY` is stale or mistyped.","commonSituations":"Corporate proxy URL changed (e.g. port moved from 3128 to 3140) but HTTPS_PROXY still has the old value; running outside the corporate VPN so the internal proxy hostname does not resolve; typo like `http://proxy.corp.example:8080` with wrong port; proxy service down; using `https://` scheme in the proxy URL when the proxy only serves plain HTTP on that port.","solutions":["Verify the proxy env vars: echo $HTTPS_PROXY/$HTTP_PROXY and confirm host and port are correct and reachable (e.g. `nc -vz <proxy_host> <proxy_port>` or `curl -x $HTTPS_PROXY https://api.example.com`)","Check DNS/VPN: ensure the proxy hostname resolves (`getent hosts <proxy_host>`) and you are on the network (VPN) that can reach it","Add the target host to NO_PROXY if the target is actually reachable directly and the proxy should be bypassed","Confirm the proxy service is running and the port matches (the parser defaults to port 80 when the URL has no port — add an explicit `:port` if your proxy listens elsewhere)","If the proxy expects credentials or a TLS-wrapped proxy connection, note this module only supports plain-HTTP CONNECT proxies; use an HTTP proxy endpoint"],"exampleFix":"// before (stale proxy in env)\nexport HTTPS_PROXY=http://old-proxy.corp.example:3128\n// after (corrected, reachable proxy)\nexport HTTPS_PROXY=http://proxy.corp.example:3140\nexport NO_PROXY=localhost,127.0.0.1,.internal.example","handlingStrategy":"validation","validationCode":"// Before connecting, validate the proxy env and reachability\nfn validate_proxy(proxy_url: &str) -> anyhow::Result<()> {\n    let url = proxy_url.trim().to_string();\n    anyhow::ensure!(!url.is_empty(), \"proxy URL is empty\");\n    let authority = url.trim_start_matches(\"http://\").trim_start_matches(\"https://\");\n    let authority = authority.split('/').next().unwrap_or(authority);\n    let (host, port) = authority\n        .rsplit_once(':')\n        .map(|(h, p)| Ok::<_, anyhow::Error>((h.to_string(), p.parse::<u16>()?)))\n        .unwrap_or_else(|| Ok((authority.to_string(), 80)))?;\n    anyhow::ensure!(!host.is_empty(), \"proxy host is empty in '{proxy_url}'\");\n    Ok(())\n}\n// Optionally pre-check reachability: std::net::TcpStream::connect((host.as_str(), port))","typeGuard":null,"tryCatchPattern":"match connect_via_proxy(&proxy_url, host, 443).await {\n    Err(e) if e.to_string().starts_with(\"Failed to connect to proxy\") => {\n        eprintln!(\"Proxy unreachable at '{proxy_url}': check HTTPS_PROXY/HTTP_PROXY and VPN\");\n        // fall back to direct connection if NO_PROXY policy allows\n    }\n    r => r?,\n}","preventionTips":["Keep HTTPS_PROXY/HTTP_PROXY accurate when the corporate proxy host/port changes","Use NO_PROXY for internal/directly-reachable hosts","Pre-validate the proxy with a cheap TCP probe (or curl -x) before starting long-lived WebSocket sessions","Remember the parser defaults to port 80 when no port is given — always include :port","Verify VPN/network reachability of internal proxy hostnames"],"tags":["network","proxy","tcp","connect"],"backgroundTag":"proxy-connection-failed","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}