BoundaryML/baml · error

Failed to create HTTP client

Error message

Failed to create HTTP client: {e}

What it means

In get_playground_dist, the server builds a reqwest HTTP client (with 30s request / 10s connect timeouts) to query the GitHub API for a playground release. If reqwest cannot construct the client (TLS backend initialization failure, resolver errors, invalid settings), the error is wrapped with this message. It happens before any network request is sent.

Solutions

  1. Ensure the runtime image includes system CA certificates (e.g. install ca-certificates in the Docker image).
  2. Check that the TLS backend dependencies (rustls or native-tls/OpenSSL) are correctly built for the target platform.
  3. Rebuild with a known-good TLS feature configuration for reqwest (e.g. default-tls vs rustls-tls, not conflicting both).
Defensive patterns

Strategy: try-catch

Try / catch

// fall back to bundled dist if client cannot be built
match get_playground_dist().await {
    Err(e) if e.to_string().contains("Failed to create HTTP client") => {
        use_bundled_playground_dist();
    }
    other => other?,
}

Prevention

When it happens

Trigger: reqwest::Client::builder().build() returns Err inside get_playground_dist, e.g. because the TLS backend failed to initialize or the system resolver/config is broken.

Common situations: Deploying in a minimal container without CA certificates, breaking rustls/native-tls initialization; corrupted or incompatible OpenSSL on the host; a build with conflicting TLS feature flags.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/9994120914e8eb08. Report an issue: GitHub.

Appendix: source

Thrown at engine/playground-server/src/server.rs:126

/// Downloads and extracts the playground frontend from the baml GitHub release.
/// Uses the provided version for both asset name construction and release tag lookup.
/// Returns the path to the directory containing the static files to serve (may be a nested 'dist' directory).
pub async fn get_playground_dist(github_repo: &str, version: &str) -> anyhow::Result<String> {
    // Construct versioned asset names
    let web_panel_asset_name = format!("playground-dist-{version}.tar.gz");
    let checksum_asset_name = format!("playground-dist-{version}.tar.gz.sha256");

    // Build the GitHub API URL using the version as the release tag
    let api_url = format!("https://api.github.com/repos/{github_repo}/releases/tags/{version}");
    tracing::info!("Fetching web-panel release metadata from: {}", api_url);

    // Fetch release metadata with timeout
    let client = reqwest::Client::builder()
        .timeout(Duration::from_secs(30))
        .connect_timeout(Duration::from_secs(10))
        .build()
        .map_err(|e| anyhow::anyhow!("Failed to create HTTP client: {e}"))?;

    tracing::info!("Sending request to GitHub API...");
    let resp = client
        .get(&api_url)
        .header("User-Agent", "baml-playground-server")
        .send()
        .await
        .map_err(|e| anyhow::anyhow!("Failed to fetch release metadata: {e}"))?;

    tracing::info!("Received response with status: {}", resp.status());

    // Check if the response is successful
    if !resp.status().is_success() {
        let status = resp.status();
        let body = resp
            .text()
            .await
            .unwrap_or_else(|_| "Failed to read response body".to_string());

View on GitHub (pinned to bd85ce9dee)