Zackriya-Solutions/meetily · error · anyhow::Error
Failed to create download client: {}
Error message
Failed to create download client: {} What it means
download_model_with_owner builds an HTTP client via reqwest's Client::builder() (with a Meetily/... user agent) before fetching the model. If reqwest fails to construct the client — almost always TLS backend initialization failure (e.g. rustls or native-tls/openssl can't initialize, missing root store, or invalid default TLS configuration) — the builder's error is wrapped in this anyhow message and the download aborts before any network request.
Source
Thrown at frontend/src-tauri/src/whisper_engine/whisper_engine.rs:1146
}
if !self.models_dir.exists() {
fs::create_dir_all(&self.models_dir)
.await
.map_err(|e| anyhow!("Failed to create models directory: {}", e))?;
}
{
let mut models = self.available_models.write().await;
if let Some(model_info) = models.get_mut(model_name) {
model_info.status = ModelStatus::Downloading { progress: 0 };
}
}
let client = Client::builder()
.user_agent(concat!("Meetily/", env!("CARGO_PKG_VERSION")))
.build()
.map_err(|e| anyhow!("Failed to create download client: {}", e))?;
let response = tokio::select! {
biased;
_ = active_download.cancellation.cancelled() => return Err(DownloadCancelled.into()),
response = client.get(model_url).send() => response
.map_err(|e| anyhow!("Failed to start download: {}", e))?,
};
if !response.status().is_success() {
return Err(anyhow!("Download failed with status: {}", response.status()));
}
let total_size = response.content_length().unwrap_or(0);
let mut file = fs::File::create(file_path)
.await
.map_err(|e| anyhow!("Failed to create file: {}", e))?;
use futures_util::StreamExt;
let mut stream = response.bytes_stream();View on GitHub (pinned to a2cb62e827)
Solutions
- Check the wrapped error text after the colon — it names the real cause (TLS/crypto provider, OpenSSL, etc.) and fix that first.
- If using rustls 0.23 with multiple crypto providers, install one explicitly at startup: rustls::crypto::ring::default_provider().install_default().
- On Linux, install OpenSSL development packages (libssl-dev) or switch Cargo features to the rustls TLS backend.
- Ensure CA certificates exist in the environment (ca-certificates package on Alpine/slim containers).
- Align reqwest features in Cargo.toml with the intended TLS backend and rebuild cleanly (cargo clean) to remove stale linking.
Example fix
// before: relies on default crypto provider, fails when 2 are linked
let client = Client::builder()
.user_agent(concat!("Meetily/", env!("CARGO_PKG_VERSION")))
.build()
.map_err(|e| anyhow!("Failed to create download client: {}", e))?;
// after: install a concrete rustls provider before building any client
rustls::crypto::ring::default_provider()
.install_default()
.expect("failed to install rustls crypto provider");
let client = Client::builder()
.user_agent(concat!("Meetily/", env!("CARGO_PKG_VERSION")))
.build()
.map_err(|e| anyhow!("Failed to create download client: {}", e))?; Defensive patterns
Strategy: try-catch
Validate before calling
// at app startup, fail fast if the TLS stack can't init
fn http_stack_ok() -> bool {
reqwest::Client::builder().build().is_ok()
}
if !http_stack_ok() {
eprintln!("HTTP/TLS stack unavailable; model downloads disabled");
} Try / catch
let client = reqwest::Client::builder()
.user_agent(concat!("Meetily/", env!("CARGO_PKG_VERSION")))
.build()
.map_err(|e| {
eprintln!("client build failed: {e}"); // surface TLS root cause
anyhow!("Failed to create download client: {}", e)
})?; Prevention
- Install an explicit rustls crypto provider at startup if using rustls 0.23 with ring and aws-lc-rs both in the tree.
- Keep reqwest's TLS feature flags consistent (avoid mixing native-tls and rustls features).
- On Linux build/packaging machines, ensure libssl-dev and ca-certificates are installed.
- Add a startup smoke test that builds a Client and performs a HEAD request to huggingface.co.
When it happens
Trigger: Client::builder().user_agent(...).build() returns Err: TLS backend init failure (openssl not linked, rustls without a crypto provider installed when multiple ring/aws-lc-rs versions are linked), invalid global default settings, or resource exhaustion during client construction.
Common situations: Building on Linux without OpenSSL dev headers when the native-tls feature is enabled; a dependency bump links two rustls crypto providers so no default is installed (rustls 0.23 'no process-level CryptoProvider' panic/error); stripped-down container/distro missing CA certificates that the TLS layer requires at init.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Failed to preserve {} after timeout: {}
- Failed to start download: {}
- Failed to read chunk: {}
- Retry failed for {}: {}
- Download timeout - No data received for 30 seconds
AI-assisted analysis of Zackriya-Solutions/meetily@a2cb62e827 (2026-09-12).
Data as JSON: /api/errors/d4b85bbf20b1d9ad.
Report an issue: GitHub.