jdx/mise · error
HTTP download timed out after
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
mise's HTTP downloader enforces a total timeout per download attempt (configurable via the `http_download_timeout` setting / `MISE_HTTP_DOWNLOAD_TIMEOUT` env). When a transfer exceeds it, the partial download is validated/handled and this error reports the elapsed timeout, URL, attempt number, and bytes received so far.
Solutions
- Increase the timeout: set `http_download_timeout` in settings or export MISE_HTTP_DOWNLOAD_TIMEOUT (e.g. to a larger duration) and retry.
- Retry the download — it resumes from the validated partial instead of starting over.
- Check network/proxy throughput; try a different mirror or network if transfers stall repeatedly.
Example fix
// before $ mise install node@22 // after (allow longer downloads) $ MISE_HTTP_DOWNLOAD_TIMEOUT=30m mise install node@22 // or in settings.toml [settings] http_download_timeout = "30m"
Defensive patterns
Strategy: retry
Validate before calling
[ -n "$MISE_HTTP_DOWNLOAD_TIMEOUT" ] && echo "timeout: $MISE_HTTP_DOWNLOAD_TIMEOUT" || echo "using default; large downloads may need more"
Try / catch
for i in 1 2 3; do MISE_HTTP_DOWNLOAD_TIMEOUT=30m mise install node@22 && break echo "download timed out (attempt $i); retrying" done
Prevention
- Raise http_download_timeout/MISE_HTTP_DOWNLOAD_TIMEOUT on slow links or big artifacts
- Ensure downloads resume (validated partials) so retries are cheap
- Avoid throttling proxies for large tool downloads
When it happens
Trigger: Downloading a large artifact over a slow or stalled connection where total elapsed time exceeds the configured http_download_timeout; a hung server that stops sending data mid-transfer.
Common situations: Large tool archives on slow corporate networks or flaky Wi-Fi; proxies throttling long transfers; CI runners with constrained bandwidth hitting the default timeout.
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
- download cancelled by user
- should not be called for system tool
- blob chunk upload failed
- blob upload failed
- {}
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/9a640aed7fbc994e.
Report an issue: GitHub.
Appendix: source
Thrown at src/http.rs:1048
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 533346cc37)