{"record":{"id":"87015f74632571c4","repo":"aaif-goose/goose","slug":"download-failed-after-retries","errorCode":null,"errorMessage":"Download failed after {} retries: {}","messagePattern":"Download failed after (.+?) retries: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-download-manager/src/lib.rs","lineNumber":483,"sourceCode":"            let _ = tokio::fs::remove_file(&partial_path).await;\n        }\n\n        loop {\n            if Self::is_cancelled(downloads, model_id) {\n                let _ = tokio::fs::remove_file(&partial_path).await;\n                anyhow::bail!(\"Download cancelled\");\n            }\n\n            let mut request = Self::apply_bearer_token(client.get(url), bearer_token);\n            if file_bytes > 0 {\n                request = request.header(\"Range\", format!(\"bytes={}-\", file_bytes));\n            }\n\n            let response = match request.send().await {\n                Ok(r) => r,\n                Err(e) => {\n                    if retries >= Self::MAX_RETRIES {\n                        anyhow::bail!(\"Download failed after {} retries: {}\", retries, e);\n                    }\n                    retries += 1;\n                    let delay = std::cmp::min(\n                        Self::RETRY_BASE_DELAY * 2u32.saturating_pow(retries - 1),\n                        Self::RETRY_MAX_DELAY,\n                    );\n                    info!(model_id = %model_id, retry = retries, delay_secs = ?delay.as_secs(), error = %e, \"Retrying download after connection error\");\n                    Self::cancellable_sleep(delay, downloads, model_id).await?;\n                    continue;\n                }\n            };\n\n            let status = response.status();\n            if status == reqwest::StatusCode::RANGE_NOT_SATISFIABLE {\n                if file_total > 0 && file_bytes == file_total {\n                    break;\n                }\n                *cumulative_bytes = cumulative_bytes.saturating_sub(file_bytes);","sourceCodeStart":465,"sourceCodeEnd":501,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-download-manager/src/lib.rs#L465-L501","documentation":"The initial reqwest request.send() failed at the transport level and the retry counter had already reached MAX_RETRIES = 10. Attempts used exponential backoff (2s doubling, capped at 60s) through cancellable_sleep; the final underlying reqwest error (DNS failure, connect refused/timeout, TLS error, proxy error) is included in the message. The client uses a 30s connect timeout.","triggerScenarios":"Ten consecutive send() failures for one file: no DNS resolution for the HF host, unreachable network, firewall or TLS-intercepting proxy rejecting the connection, or wrong HTTP(S)_PROXY environment variables.","commonSituations":"Offline machines, corporate proxies requiring auth, VPN split-tunnel dropping huggingface.co, captive portals, IPv6 misconfiguration, CDN regional outages sustained across the full backoff window.","solutions":["Verify basic reachability: curl -I on the exact URL from the same machine and environment","Check HTTP_PROXY / HTTPS_PROXY / NO_PROXY settings and VPN/pro interference","Fix DNS or switch networks, then restart the download (it resumes from the .partial file)","If the host is temporarily down, retry after the outage clears"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// cheap preflight before a long download: HEAD must reach the host\nlet ok = reqwest::Client::new().head(url).send().await.map(|r| r.status().is_success()).unwrap_or(false);\nif !ok { /* fix connectivity/proxy first; do not enter the download loop */ }","typeGuard":null,"tryCatchPattern":"if err.to_string().starts_with(\"Download failed after\") {\n    // library already did 10 attempts with backoff: run a connectivity check,\n    // fix DNS/proxy/VPN, then restart the download - it resumes from the .partial file\n}","preventionTips":["Verify HTTP(S)_PROXY/NO_PROXY in the deployment environment before large downloads","Preflight with a HEAD request to fail fast on unreachable hosts","Expose the appended reqwest error to the user: it distinguishes DNS vs TLS vs proxy failures"],"tags":["rust","network","download","retry","huggingface"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}