seanmonstar/reqwest · critical

Client::new()

Error message

Client::new()

What it means

Client::new() (src/async_impl/client.rs:2523-2525) calls ClientBuilder::new().build().expect("Client::new()"). ClientBuilder::build() returns crate::Result<Client> and fails if a TLS backend cannot be initialized, the DNS resolver cannot load system configuration, a config error was recorded on the builder, or (with rustls-no-provider) no crypto provider was installed (see the panic at client.rs:2500-2507 for context). Because new() uses .expect(), any such failure aborts the process with the panic message 'Client::new()'. The doc comment on new() explicitly warns of this and points to Client::builder() for fallible construction.

Source

Thrown at src/async_impl/client.rs:2524

        See https://docs.rs/rustls/latest/rustls/#cryptography-providers for details."
    );

    #[cfg(feature = "__rustls-aws-lc-rs")]
    Arc::new(rustls::crypto::aws_lc_rs::default_provider())
}

impl Client {
    /// Constructs a new `Client`.
    ///
    /// # Panics
    ///
    /// This method panics if a TLS backend cannot be initialized, or the resolver
    /// cannot load the system configuration.
    ///
    /// Use `Client::builder()` if you wish to handle the failure as an `Error`
    /// instead of panicking.
    pub fn new() -> Client {
        ClientBuilder::new().build().expect("Client::new()")
    }

    /// Creates a `ClientBuilder` to configure a `Client`.
    ///
    /// This is the same as `ClientBuilder::new()`.
    pub fn builder() -> ClientBuilder {
        ClientBuilder::new()
    }

    /// Convenience method to make a `GET` request to a URL.
    ///
    /// # Errors
    ///
    /// This method fails whenever the supplied `Url` cannot be parsed.
    pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
        self.request(Method::GET, url)
    }

View on GitHub (pinned to 9f06fd28ab)

Solutions

  1. Replace Client::new() with Client::builder().build()? so failures return a Result instead of panicking, and handle the error.
  2. Install ca-certificates in the container (apt-get install ca-certificates / apk add ca-certificates) or bundle roots via .add_root_certificate().
  3. If using rustls-no-provider, install a provider before building: rustls::crypto::aws_lc_rs::default_provider().install_default().unwrap();
  4. For missing resolv.conf, mount /etc/resolv.conf in the container or supply a custom resolver via .dns_resolver().

Example fix

// before
let client = reqwest::Client::new();

// after
let client = match reqwest::Client::builder().build() {
    Ok(c) => c,
    Err(e) => {
        eprintln!("failed to build reqwest client: {e}");
        std::process::exit(1);
    }
};
Defensive patterns

Strategy: try-catch

Validate before calling

// There is no fallible validation before build(); the fix is to use the fallible builder.
// Pre-flight: ensure a crypto provider is installed when rustls-no-provider is on.
#[cfg(feature = "rustls-no-provider")]
fn ensure_crypto_provider() {
    let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
}

Try / catch

// never use Client::new(); always:
let client = match reqwest::Client::builder().build() {
    Ok(c) => c,
    Err(e) => {
        eprintln!("reqwest client build failed: {e}");
        // degrade gracefully or exit
        std::process::exit(1);
    }
};

Prevention

When it happens

Trigger: Calling Client::new() on a system with missing/broken root certificate stores (e.g. minimal containers without ca-certificates). Building with the 'rustls-no-provider' feature and forgetting to install a CryptoProvider before Client::new(). A GaiResolver failing to load /etc/resolv.conf or a hickory-dns resolver failing its config. Setting an invalid TLS config on the builder that surfaces as config.error inside build() (client.rs:412-414).

Common situations: Alpine / distroless / scratch Docker images without ca-certificates installed. Switching from default native-tls to rustls with the no-provider feature to reduce binary size and forgetting the install_default() call. Sandboxed environments where /etc/resolv.conf is absent. CI runners with restricted system config.

Related errors


AI-assisted analysis of seanmonstar/reqwest@9f06fd28ab (2026-08-10). Data as JSON: /api/errors/f5a52a839d885ba9. Report an issue: GitHub.