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",
);
}
bodyView on GitHub (pinned to acf2587e46)
Solutions
- 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).
- Inspect proxy env vars (HTTPS_PROXY etc.) for malformed URLs and fix or unset them.
- Check TLS backend health: ensure rustls-tls or native-tls feature is compiled in and CA certs are present (SSL_CERT_FILE / ca-certificates).
- 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
- Sanitize API keys before inserting as header values (visible ASCII only).
- Validate proxy env vars in startup checks.
- Ship CA certificates in CLI container images.
- Test the CLI in clean environments (no proxy vars, minimal images) in CI.
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
- Failed to build HTTP client
- Failed to build HTTP client
- Failed to listen for SIGTERM
- Failed to create Tokio runtime
- Failed to draw
AI-assisted analysis of RightNow-AI/openfang@acf2587e46 (2026-09-02).
Data as JSON: /api/errors/98db6762f0e9985c.
Report an issue: GitHub.