windmill-labs/windmill · error

Failed to build AI HTTP client - check system TLS configurat

Error message

Failed to build AI HTTP client - check system TLS configuration

What it means

Raised when building the pooled reqwest AI HTTP client fails at initialization — practically always a TLS backend problem (missing OpenSSL/rustls configuration, broken system certs). It is an environment/setup error on the host, not a request-time failure; the AI client static could not be constructed at all.

Source

Thrown at backend/windmill-ai/src/utils.rs:35

    /// HTTP client for anything targeting a user-configured AI provider `base_url`;
    /// use it instead of the shared `HTTP_CLIENT`. Redirects are governed by
    /// `ALLOW_AI_BASE_URL_REDIRECTS` (disabled by default). Mirrors the API proxy
    /// client (windmill-api/src/ai.rs).
    ///
    /// This pooled client does no DNS pinning: callers reaching a user-controlled
    /// base_url must go through [`pinned_ai_client_for`] so the connect targets
    /// the SSRF-validated address (DNS-rebinding TOCTOU). It is the safe default
    /// only for trusted/fixed hosts.
    pub static ref AI_HTTP_CLIENT: reqwest::Client = {
        if *ALLOW_AI_BASE_URL_REDIRECTS {
            tracing::warn!(
                "ALLOW_AI_BASE_URL_REDIRECTS is enabled - the AI HTTP client will follow \
                 redirects, weakening SSRF protection on provider base URLs"
            );
        }
        ai_http_client_builder()
            .build()
            .expect("Failed to build AI HTTP client - check system TLS configuration")
    };

    /// Parse AI_HTTP_HEADERS environment variable into a vector of (header_name, header_value) tuples
    /// Format: "header1: value1, header2: value2"
    pub static ref AI_HTTP_HEADERS: Vec<(String, String)> = {
        std::env::var("AI_HTTP_HEADERS")
            .ok()
            .map(|headers_str| {
                headers_str
                    .split(',')
                    .filter_map(|header| {
                        let parts: Vec<&str> = header.splitn(2, ':').collect();
                        if parts.len() == 2 {
                            let name = parts[0].trim().to_string();
                            let value = parts[1].trim().to_string();
                            if !name.is_empty() && !value.is_empty() {
                                Some((name, value))
                            } else {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Install/repair system CA certificates (e.g. ca-certificates package) on the host
  2. Ensure OpenSSL libraries are present and version-compatible with the build
  3. If behind a corporate proxy, configure proxy env vars and its CA cert appropriately
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at backend/windmill-ai/src/utils.rs:35 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


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