xai-org/grok-build · error

Proxy CONNECT failed: {}

Error message

Proxy CONNECT failed: {}

What it means

open_connect_tunnel sends an HTTP CONNECT request through the configured proxy and requires the first response line to be HTTP/1.0 or HTTP/1.1 with status 200. Anything else (403, 407, 502, or a malformed line) is bailed as "Proxy CONNECT failed: {status_line}" — the proxy refused or could not establish the tunnel to the target host.

Source

Thrown at crates/codegen/xai-grok-shell/src/agent/proxy.rs:170

    // 3. Send HTTP CONNECT.
    let connect_req = format!(
        "CONNECT {target_host}:{target_port} HTTP/1.1\r\n\
         Host: {target_host}:{target_port}\r\n\
         \r\n"
    );
    let (reader_half, mut writer_half) = stream.into_split();
    writer_half.write_all(connect_req.as_bytes()).await?;
    writer_half.flush().await?;

    // 4. Read the status line from the proxy.
    let mut reader = BufReader::new(reader_half);
    let mut status_line = String::new();
    reader.read_line(&mut status_line).await?;
    debug!(status_line = %status_line.trim(), "Proxy CONNECT response");

    if !status_line.starts_with("HTTP/1.1 200") && !status_line.starts_with("HTTP/1.0 200") {
        anyhow::bail!("Proxy CONNECT failed: {}", status_line.trim());
    }

    // Consume remaining response headers (until empty line).
    loop {
        let mut line = String::new();
        reader.read_line(&mut line).await?;
        if line.trim().is_empty() {
            break;
        }
    }

    // 5. Assert the BufReader's internal buffer is empty before reuniting.
    // BufReader::read_line may have read ahead into its buffer. If extra
    // bytes were consumed beyond the HTTP headers (e.g., from a proxy that
    // eagerly forwards data or coalesced TCP segments), dropping them would
    // corrupt the subsequent TLS handshake.
    let remaining = reader.buffer();
    if !remaining.is_empty() {

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Read the status line in the message: 407 means add proxy credentials (e.g. http://user:pass@proxy:port in the proxy URL).
  2. Confirm the proxy supports the CONNECT method and HTTPS tunneling (not SOCKS or plain-HTTP-only).
  3. Ask network admin to allowlist the target relay host/port if the proxy returns 403.
  4. Verify the proxy address/port in proxy environment variables or config are correct and reachable.

Example fix

// before
let proxy = "http://proxy.corp:3128"; // 407: no creds
// after
let proxy = "http://user:password@proxy.corp:3128";
Defensive patterns

Strategy: validation

Validate before calling

// validate proxy config before connecting
fn check_proxy(proxy_url: &str) -> Result<(), String> {
    let u = url::Url::parse(proxy_url).map_err(|e| e.to_string())?;
    if u.scheme() != "http" && u.scheme() != "https" {
        return Err(format!("proxy scheme '{}' does not support CONNECT; use http(s)", u.scheme()));
    }
    Ok(())
}

Try / catch

match connect_via_proxy(target, &proxy).await {
    Err(e) if e.to_string().starts_with("Proxy CONNECT failed") => {
        let status = extract_status(&e.to_string());
        match status {
            407 => return Err(anyhow!("proxy auth required: add user:pass to proxy URL")),
            403 => return Err(anyhow!("proxy blocks target host; request allowlisting")),
            _ => return Err(e),
        }
    }
    other => other,
}

Prevention

When it happens

Trigger: Proxy responds to CONNECT with a non-200 status line — proxy auth required (407), target blocked by policy (403), proxy cannot reach the target (502/504), or a non-HTTP proxy endpoint replying with garbage.

Common situations: Missing proxy credentials (407 Proxy-Authentication-Required); corporate proxy ACLs blocking the relay host; pointing HTTPS_PROXY at a SOCKS proxy or plain HTTP port that doesn't support CONNECT; proxy outage.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/2ef08bad99046bf2. Report an issue: GitHub.