windmill-labs/windmill · critical

client build

Error message

client build

What it means

After building the Bearer header, create_client constructs the reqwest HTTP client with reqwest::ClientBuilder::build().expect("client build"). reqwest's build fails when the TLS backend cannot be initialized (no root certificates / broken native-tls or rustls setup) or when the builder options are inconsistent. Because expect is used, any such failure panics rather than returning a Result.

Source

Thrown at backend/windmill-api-client/src/lib.rs:183

        } else {
            Err(Error::UnexpectedResponse(
                response.status().as_u16(),
                response.text().await.unwrap_or_default(),
            ))
        }
    }
}

/// Create a client with bearer token authentication
pub fn create_client(base_url: &str, token: String) -> Client {
    let mut val = HeaderValue::from_str(&format!("Bearer {token}")).expect("header creation");
    val.set_sensitive(true);
    let mut headers = HeaderMap::new();
    headers.insert(AUTHORIZATION, val);
    let client = reqwest::ClientBuilder::new()
        .default_headers(headers)
        .build()
        .expect("client build");
    Client::new_with_client(&format!("{}/api", base_url.trim_end_matches('/')), client)
}

/// Error type for API client
#[derive(Debug)]
pub enum Error {
    /// Request error
    Request(reqwest::Error),
    /// Unexpected response status
    UnexpectedResponse(u16, String),
}

impl From<reqwest::Error> for Error {
    fn from(err: reqwest::Error) -> Self {
        Error::Request(err)
    }
}

View on GitHub (pinned to e474e8803c)

Solutions

  1. Install CA certificates in the runtime environment (e.g. apk add ca-certificates, apt-get install ca-certificates).
  2. If using rustls, ensure add_included_root_certs or webpki-roots feature is enabled; if native-tls, ensure OpenSSL is present.
  3. Check SSL_CERT_FILE / SSL_CERT_DIR env vars point to real certificate bundles.
  4. If you control the library, propagate the build error (Result<Client, Error>) instead of .expect so the underlying reqwest message is reported.

Example fix

// before (library)
.build().expect("client build");

// after (library, propagate instead of panic)
.build().map_err(|e| Error::Reqwest(e))
Defensive patterns

Strategy: fallback

Validate before calling

// before calling create_client in a container, ensure CA certs exist:
// std::path::Path::new("/etc/ssl/certs/ca-certificates.crt").exists()

Try / catch

// panic-based expect: catch at process boundary if you cannot change the library
let client = std::panic::catch_unwind(|| create_client(url, token))
    .unwrap_or_else(|_| fallback_insecure_client(url));

Prevention

When it happens

Trigger: Calling create_client in an environment where reqwest cannot initialize its connector/TLS backend: missing system CA bundle, a rustls/native-tls misconfiguration, or an invalid reqwest feature set for the target platform.

Common situations: Deploying to a minimal/stripped container image without /etc/ssl/certs; cross-compiled binaries where native-tls/OpenSSL is unavailable; Alpine/musl builds missing CA certificates; environment variable SSL_CERT_FILE/SSL_CERT_DIR pointing at nonexistent paths.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/a42d5b041e3a811a. Report an issue: GitHub.