Y2Z/monolith · critical

Failed to initialize HTTP client

Error message

Failed to initialize HTTP client

What it means

Session::new builds a reqwest blocking HTTP client and calls .expect("Failed to initialize HTTP client") on Client::builder().build(), which panics if reqwest cannot construct the client. Build failures are almost always caused by an invalid default header value (e.g. a User-Agent containing non-visible-ASCII characters) or TLS backend initialization problems. Because the constructor returns Self rather than a Result, the panic aborts the process instead of returning an error.

Source

Thrown at src/session.rs:47

        let mut header_map = HeaderMap::new();
        if let Some(user_agent) = &options.user_agent {
            header_map.insert(
                USER_AGENT,
                HeaderValue::from_str(user_agent).expect("Invalid User-Agent header specified"),
            );
        }
        let client = Client::builder()
            .timeout(Duration::from_secs(if options.timeout > 0 {
                options.timeout
            } else {
                // We have to specify something that eventually makes the program fail
                // (prevent it from hanging forever)
                600 // 10 minutes in seconds
            }))
            .danger_accept_invalid_certs(options.insecure)
            .default_headers(header_map)
            .build()
            .expect("Failed to initialize HTTP client");

        Session {
            cache,
            cookies,
            client,
            options,
            urls: Vec::new(),
        }
    }

    pub fn retrieve_asset(
        &mut self,
        parent_url: &Url,
        url: &Url,
    ) -> Result<(Vec<u8>, Url, String, String), reqwest::Error> {
        let cache_key: String = clean_url(url.clone()).as_str().to_string();

        if !self.urls.contains(&url.as_str().to_string()) {

View on GitHub (pinned to a6fc8d0095)

Solutions

  1. Sanitize or replace the user_agent option so it contains only visible ASCII characters before calling Session::new
  2. Check that the reqwest TLS feature (default-tls/native-tls or rustls-tls) matches the target platform and its TLS runtime is available
  3. If embedding the library, patch/vendor the constructor to return Result<Self, reqwest::Error> and propagate the build error instead of expect()
  4. Call reqwest::blocking::Client::builder().build() in a smoke test to confirm the failure is in client construction, not Session::new itself

Example fix

// before
let user_agent = options.user_agent.clone().unwrap_or_default();
Session::new(None, None, options_with(user_agent));
// after
let user_agent = options.user_agent.clone().unwrap_or_default();
assert!(user_agent.is_ascii() && !user_agent.chars().any(|c| c.is_control()), "user-agent must be visible ASCII");
Session::new(None, None, options_with(user_agent));
Defensive patterns

Strategy: validation

Validate before calling

fn validate_user_agent(ua: &Option<String>) -> Result<(), String> {
    match ua {
        Some(s) if s.is_ascii() && !s.chars().any(|c| c.is_control()) && !s.is_empty() => Ok(()),
        Some(s) => Err(format!("invalid user-agent header value: {:?}", s)),
        None => Ok(()),
    }
}

Type guard

fn is_valid_header_value(v: &str) -> bool {
    v.is_ascii() && v.bytes().all(|b| (32..=126).contains(&b) || b == b'\t')
}

Prevention

When it happens

Trigger: Calling Session::new with MonolithOptions whose user_agent contains characters invalid for an HTTP header value (non-ASCII/control chars, or an empty None-checked value that fails HeaderValue::from_str is separately panicked earlier); or the reqwest TLS backend fails to initialize (missing/mismatched native-tls or rustls setup at build time).

Common situations: Passing a User-Agent string copied from somewhere containing non-Latin1 characters (emoji, CJK) or control characters; linking reqwest with default-tls/native-tls features on a system without an OpenSSL runtime; embedding the library in an environment where TLS init fails.

Related errors


AI-assisted analysis of Y2Z/monolith@a6fc8d0095 (2026-09-05). Data as JSON: /api/errors/6d3c7b15d95b5331. Report an issue: GitHub.