RightNow-AI/openfang · error

Failed to build HTTP client

Error message

Failed to build HTTP client

What it means

reqwest::blocking::Client::builder().build() returns Err when the client cannot be constructed — most often TLS backend initialization failure (rustls/native-tls root store issues) or an invalid configuration on the builder (bad timeout, invalid header). The CLI panics with expect, aborting the process since the daemon HTTP client is essential.

Source

Thrown at crates/openfang-cli/src/main.rs:1205

/// Build an HTTP client for daemon calls.
///
/// When api_key is configured in config.toml, the client automatically
/// includes a `Authorization: Bearer <key>` header on every request.
/// When api_key is empty or missing, no auth header is sent.
pub(crate) fn daemon_client() -> reqwest::blocking::Client {
    let mut builder =
        reqwest::blocking::Client::builder().timeout(std::time::Duration::from_secs(120));

    if let Some(key) = read_api_key() {
        let mut headers = reqwest::header::HeaderMap::new();
        if let Ok(val) = reqwest::header::HeaderValue::from_str(&format!("Bearer {key}")) {
            headers.insert(reqwest::header::AUTHORIZATION, val);
        }
        builder = builder.default_headers(headers);
    }

    builder.build().expect("Failed to build HTTP client")
}

/// Helper: send a request to the daemon and parse the JSON body.
/// Exits with error on connection failure.
pub(crate) fn daemon_json(
    resp: Result<reqwest::blocking::Response, reqwest::Error>,
) -> serde_json::Value {
    match resp {
        Ok(r) => {
            let status = r.status();
            let body = r.json::<serde_json::Value>().unwrap_or_default();
            if status.is_server_error() {
                ui::error_with_fix(
                    &format!("Daemon returned error ({})", status),
                    "Check daemon logs: ~/.openfang/tui.log",
                );
            }
            body

View on GitHub (pinned to acf2587e46)

Solutions

  1. Validate/sanitize the API key before inserting it (strip non-visible-ASCII, or skip the header on from_str failure — the code does check from_str but verify the key itself).
  2. Inspect proxy env vars (HTTPS_PROXY etc.) for malformed URLs and fix or unset them.
  3. Check TLS backend health: ensure rustls-tls or native-tls feature is compiled in and CA certs are present (SSL_CERT_FILE / ca-certificates).
  4. Replace .expect with error propagation and a user-facing message plus retry with default Client::new().

Example fix

// before
builder.build().expect("Failed to build HTTP client")
// after
builder.build().unwrap_or_else(|e| {
    eprintln!("warning: custom client build failed ({e}); using default client");
    reqwest::blocking::Client::new()
})
Defensive patterns

Strategy: fallback

Validate before calling

// Check environment before building the client
fn client_env_ok() -> Result<(), String> {
    for v in ["HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"] {
        if let Ok(p) = std::env::var(v) {
            if p.parse::<url::Url>().is_err() {
                return Err(format!("{v} is not a valid URL: {p}"));
            }
        }
    }
    Ok(())
}

Try / catch

// match on Result instead of expect
let client = match builder.build() {
    Ok(c) => c,
    Err(e) => {
        eprintln!("error: cannot build HTTP client: {e}");
        std::process::exit(1);
    }
};

Prevention

When it happens

Trigger: Client::builder()...build() returns Err: invalid default header values inserted (e.g. AUTHORIZATION header built from a key containing non-visible-ASCII characters that slipped past from_str), TLS backend init failure, or system proxy configuration that reqwest cannot parse.

Common situations: API key/env var containing newline or non-ASCII bytes used in the Authorization header; corporate proxy env vars (http_proxy/https_proxy) with malformed URLs; missing/incorrectly built TLS root certificates in the container.

Related errors


AI-assisted analysis of RightNow-AI/openfang@acf2587e46 (2026-09-02). Data as JSON: /api/errors/98db6762f0e9985c. Report an issue: GitHub.