janhq/jan · critical
Failed to create fallback client
Error message
Failed to create fallback client
What it means
This is a panic (.expect) from reqwest::Client::builder().build() inside the Anthropic-to-OpenAI fallback path of the proxy server. Client::build() fails when the TLS backend cannot be initialized — on Linux this usually means native-tls cannot find CA certificates (no ca-certificates package, no SSL_CERT_FILE env var). The fallback creates a fresh client to avoid connection pool contamination from the primary request.
Source
Thrown at src-tauri/src/core/server/proxy.rs:2728
// Transform body to OpenAI format for fallback
if let Some((url, openai_body)) = fallback_url.zip(fallback_body).and_then(|(url, body)| {
let json_body = serde_json::from_slice::<serde_json::Value>(&body).ok()?;
match transform_anthropic_to_openai(&json_body) {
Some(transformed) => Some((url, transformed)),
None => {
log::error!("transform_anthropic_to_openai returned None for body: {json_body}");
None
}
}
}) {
let chat_url = format!("{}/chat/completions", url);
log::info!("Fallback to chat completions: {chat_url}");
// Create a fresh client for the fallback to avoid connection pool issues
let fallback_client = Client::builder()
.build()
.expect("Failed to create fallback client");
let mut fallback_req = fallback_client.post(&chat_url);
// Ensure Content-Type is set and prevent compression
fallback_req = fallback_req.header("Content-Type", "application/json");
fallback_req = fallback_req.header("Accept-Encoding", "identity");
for (name, value) in headers.iter() {
if name != hyper::header::HOST
&& name != hyper::header::AUTHORIZATION
&& name != "content-type"
&& name != hyper::header::CONTENT_LENGTH
&& name != hyper::header::ACCEPT_ENCODING
{
fallback_req = fallback_req.header(name, value);
}
}
if let Some(key) = fallback_api_key {View on GitHub (pinned to fad3f12a14)
Solutions
- Install CA certificates: Debian/Ubuntu `apt-get install ca-certificates`, Alpine `apk add ca-certificates`.
- Set SSL_CERT_FILE to the correct CA bundle path.
- Use rustls TLS backend instead of native-tls in the reqwest feature flags.
- Replace .expect with a proper error to avoid crashing the proxy.
Example fix
// before
let fallback_client = Client::builder()
.build()
.expect("Failed to create fallback client");
// after
let fallback_client = Client::builder()
.build()
.map_err(|e| format!("Failed to create fallback client: {e}"))?; Defensive patterns
Strategy: try-catch
Validate before calling
// At startup, verify a reqwest client can be built
fn verify_tls_available() -> bool {
reqwest::Client::builder().build().is_ok()
}
// If false, log a clear message about missing CA certificates
if !verify_tls_available() {
log::error!("reqwest client build failed; install ca-certificates and check SSL_CERT_FILE");
} Try / catch
// Replace .expect with a proper error
let fallback_client = Client::builder()
.build()
.map_err(|e| {
log::error!("Failed to create fallback HTTP client: {e}");
format!("TLS/client init failed: {e}. Check CA certificates.")
})?; Prevention
- Install ca-certificates in all Docker/container images.
- Set SSL_CERT_FILE to the correct CA bundle path.
- Prefer rustls over native-tls in reqwest features to avoid system cert issues.
- Build the client once at startup and reuse it instead of per-request construction.
- Replace .expect with .map_err in production proxy code.
When it happens
Trigger: Running on Linux without ca-certificates installed (minimal Docker images, Alpine without ca-certificates-bundle). The SSL_CERT_FILE or SSL_CERT_DIR env vars point to nonexistent paths. A corrupt system trust store. TLS backend initialization failure due to a FIPS or hardware crypto module issue.
Common situations: Docker Alpine images missing `apk add ca-certificates`. Distroless containers without root certificates. Proxied environments where MITM certs are not in the trust store. FIPS-mode kernels rejecting the TLS cipher negotiation.
Related errors
- HTTP request failed: {0}
- Response body is null
- cannot resolve current exe
- clone log file
- Failed to determine the home directory
AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12).
Data as JSON: /api/errors/ac4cafcf6ffa05a1.
Report an issue: GitHub.