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

  1. Increase the timeout: set MISE_HTTP_DOWNLOAD_TIMEOUT (or http_download_timeout in settings) to a larger duration
  2. Check network throughput; switch to a faster mirror via MISE_*_MIRROR settings for the tool
  3. Resume by retrying — partial downloads are preserved as resumable when valid
  4. 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

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.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/9a640aed7fbc994e. Report an issue: GitHub.