jdx/mise · error
HTTP download timed out after {} for {} (attempt {}, {} byte
Error message
HTTP download timed out after {} for {} (attempt {}, {} bytes received; change with `http_download_timeout` or env `MISE_HTTP_DOWNLOAD_TIMEOUT`) What it means
HTTP downloads in src/http.rs enforce a total transfer timeout (http_download_timeout setting / MISE_HTTP_DOWNLOAD_TIMEOUT env). When the download exceeds that budget, the transfer future is cancelled, any partial download is validated/cleaned up, and this error reports the elapsed duration, URL, attempt number, and bytes received so far.
Source
Thrown at src/http.rs:921
let partial = partial.clone();
async move {
attempt.fetch_add(1, Ordering::Relaxed);
bytes_received.store(0, Ordering::Relaxed);
self.download_file_attempt(request_url, headers, &partial, pr, &bytes_received)
.await
}
});
let metadata = match tokio::time::timeout(total_timeout, download).await {
Ok(result) => result?,
Err(_) => {
// A timeout cancels the transfer future before its normal cleanup
// runs. Loading the sidecar removes an unvalidated partial while
// preserving a resumable one.
if let Err(err) = partial.load() {
debug!("failed to validate partial download after timeout: {err:#}");
}
bail!(
"HTTP download timed out after {} for {} (attempt {}, {} bytes received; change with `http_download_timeout` or env `MISE_HTTP_DOWNLOAD_TIMEOUT`)",
format_duration(total_timeout),
url,
attempt.load(Ordering::Relaxed),
bytes_received.load(Ordering::Relaxed),
)
}
};
// Complete the atomic rename after the cancellable transfer budget. A
// blocking task cannot be cancelled once it starts, so keeping it out
// of `timeout` prevents us from returning an error while it can still
// install the destination in the background.
let path = path.to_path_buf();
tokio::task::spawn_blocking(move || partial.persist(&path)).await??;
Ok(metadata)
}
View on GitHub (pinned to afd2eddd3a)
Solutions
- Increase the timeout: set MISE_HTTP_DOWNLOAD_TIMEOUT (or http_download_timeout in settings) to a larger duration
- Check network throughput; switch to a faster mirror via MISE_*_MIRROR settings for the tool
- Resume by retrying — partial downloads are preserved as resumable when valid
- Verify no proxy/VPN is throttling the download; try a direct connection
Example fix
# shell # before export MISE_HTTP_DOWNLOAD_TIMEOUT=30s # after export MISE_HTTP_DOWNLOAD_TIMEOUT=600s
Defensive patterns
Strategy: try-catch
Validate before calling
// size the timeout against expected artifact size and bandwidth
let size_mb = content_length / (1024 * 1024);
let needed = size_mb as u64 * 4; // seconds/MB on a slow link
std::env::set_var("MISE_HTTP_DOWNLOAD_TIMEOUT", format!("{}s", needed.max(300))); Try / catch
match download(url, dest).await {
Err(e) if e.to_string().contains("timed out") => {
eprintln!("download timed out; retrying with larger timeout / from mirror");
download_with_fallback_mirror(url, dest).await?; // resumes from partial
}
other => other?,
} Prevention
- Set MISE_HTTP_DOWNLOAD_TIMEOUT generously for large toolchains
- Use fast regional mirrors (MISE_*_MIRROR) for big artifacts
- Ensure partial-download resume keeps working: don't wipe mise's cache mid-download
When it happens
Trigger: A large artifact download takes longer than the configured total timeout — slow network, throttled mirror, huge file, or an unreasonably low timeout setting.
Common situations: Downloading multi-hundred-MB toolchains (Node, Swift, JDK) on slow links; corporate proxies throttling; default timeout too small for the file size; congested Wi-Fi or VPN.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- should not be called for system tool
- server returned an invalid Content-Range response
- server returned inconsistent partial content
- Got HTML instead of text from {}
- cannot encode #{value.class} as JSON
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/9a640aed7fbc994e.
Report an issue: GitHub.