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
- Install CA certificates in the runtime environment (e.g. apk add ca-certificates, apt-get install ca-certificates).
- If using rustls, ensure add_included_root_certs or webpki-roots feature is enabled; if native-tls, ensure OpenSSL is present.
- Check SSL_CERT_FILE / SSL_CERT_DIR env vars point to real certificate bundles.
- 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
- Install ca-certificates in every runtime image (Alpine/musl builds especially).
- Prefer reqwest with rustls + webpki-roots features so root certs are bundled, not read from disk.
- Smoke-test client construction at startup so TLS misconfig fails fast with a clear log.
- Patch the library to return Result from create_client instead of panicking on build.
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
- WINDMILL_DIR must not be empty
- WINDMILL_DIR must not end with a trailing slash, got: {dir}
- unreachable, language is not supported: {language:#?}
- itered cannot be empty
- Failed to parse Cargo.toml.default
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/a42d5b041e3a811a.
Report an issue: GitHub.