cjpais/Handy · error · anyhow::Error
Hugging Face download failed after
Error message
Hugging Face download failed after {} attempt(s): {} What it means
Every attempt in the ATTEMPT_STREAMS schedule failed (or a single-stream attempt stalled and broke out early), and the catalog's mirror_fallbacks() list for this model is empty, so the download manager gives up and reports the attempt count plus the last hf_error. The attempt number reflects the early-exit position, not the schedule length. This is the terminal error for download_model on HuggingFace-sourced models without mirrors.
Solutions
- Verify outbound reachability of huggingface.co (curl -I https://huggingface.co) from the same machine
- Free disk space — model files are multi-GB and writes fail silently as generic errors
- Retry once network/Hub status recovers; the download resumes from the cached .sync.part
- Manually download the model file and drop it into the models dir with the expected filename (get_model_path accepts manual drop-ins)
- As a maintainer: add a mirror fallback for this model in the catalog so the mirror path can absorb Hub outages
Defensive patterns
Strategy: retry
Validate before calling
// cheap reachability preflight before a multi-GB attempt
async fn hub_reachable() -> bool {
reqwest::get("https://huggingface.co")
.await
.map(|r| r.status().is_success() || r.status() == reqwest::StatusCode::FORBIDDEN)
.unwrap_or(false)
} Try / catch
match manager.download_model(id).await {
Err(e) if e.to_string().contains("download failed after") => {
// transient/Hub-side failure with no mirror — safe to offer a user-initiated retry later
ui.show_retry_later(e);
}
other => other?,
} Prevention
- Check disk space before downloads: models are multi-GB and failures masquerade as generic errors
- Give models mirror_fallbacks entries in the catalog so Hub outages have an escape path
- Surface the trailing hf_error (it's {:?}-printed in the log) instead of just the attempt count
When it happens
Trigger: Total network outage or huggingface.co blocked by firewall/region; the HF repo was removed, renamed, or made private so every attempt fails identically; disk-full causing every write to fail; all attempts stalled sequentially on a dead link with no mirror configured.
Common situations: Corporate/region firewalls blocking huggingface.co; deprecated model repos pulled from the Hub; full disk during multi-GB downloads; transient HF outage that outlasts the retry schedule.
Related errors
- transfer stalled: no progress for
- Download failed from Hugging Face
- Failed to init Hugging Face API
- Complete model file not found in HF cache or models dir
- download incomplete: expected
AI-assisted analysis of cjpais/Handy@ba10ce1943 (2026-08-17).
Data as JSON: /api/errors/4b8e6c3099ece353.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/src/managers/model.rs:2111
_ = cancel_token.cancelled() => {
info!("HF download cancelled for: {}", model_id);
return Ok(());
}
}
attempt += 1;
}
}
};
if let Some(hf_error) = hf_error {
// `attempt`, not the schedule length: a sequential stall breaks out early.
error!(
"HF download failed for {} after {} attempt(s): {:?}",
model_id, attempt, hf_error
);
let mirrors = crate::catalog::mirror_fallbacks(&model_id);
if mirrors.is_empty() {
return Err(anyhow::anyhow!(
"Hugging Face download failed after {} attempt(s): {}",
attempt,
hf_error
));
}
let mut completed = false;
for mirror in &mirrors {
info!("Falling back to mirror for {}: {}", model_id, mirror.url);
match self
.download_from_mirror(&model_id, &filename, mirror, cancel_token.clone())
.await
{
Ok(true) => {
completed = true;
break;
}
Ok(false) => {
info!("Mirror download cancelled for: {}", model_id);View on GitHub (pinned to ba10ce1943)