wasmerio/wasmer · error

Timeout while downloading response body

Error message

Timeout while downloading response body

What it means

The WASIX reqwest-based HTTP host implementation streams the response body in chunks under a per-chunk timeout in `request`. If the timeout fires before any chunk has been downloaded (chunk_count == 0), it aborts with 'Timeout while downloading response body'. If some chunks were already received, it resets the timeout and keeps going — so this specifically means nothing at all arrived within the window.

Source

Thrown at lib/wasix/src/http/reqwest.rs:121

                        res = stream.try_next() => {
                            match res {
                                Ok(Some(chunk)) => {
                                    buf.extend_from_slice(&chunk);
                                    chunk_count += 1;
                                }
                                Ok(None) => {
                                    break 'OUTER;
                                }
                                Err(e) => {
                                    return Err(e.into());
                                }
                            }
                        }

                        _ = &mut timeout => {
                            if chunk_count == 0 {
                                tracing::warn!(timeout= "timeout while downloading response body");
                                return Err(anyhow::anyhow!("Timeout while downloading response body"));
                            } else {
                                tracing::debug!(downloaded_body_size_bytes=%buf.len(), "download progress");
                                // Timeout, but chunks were downloaded, so
                                // just continue with a fresh timeout.
                                continue 'OUTER;
                            }
                        }
                    }
                }
            }

            buf
        } else {
            response.bytes().await?.to_vec()
        };
        #[cfg(feature = "js")]
        let data = response.bytes().await?.to_vec();

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Retry the request — transient network stalls are the most common cause and succeed on retry.
  2. Check the remote server's health/logs: it likely accepted the request but never wrote a body.
  3. Verify network connectivity and that no firewall/NAT is silently dropping established connections.
  4. If behind a proxy, confirm the proxy streams chunked responses instead of buffering.
  5. Increase the body-download timeout in the WASIX HTTP configuration if the server is legitimately slow.

Example fix

// before: single attempt
let resp = http.request(req).await?;
// after: retry on body-download timeout
let resp = match http.request(req.clone()).await {
    Ok(r) => r,
    Err(e) if e.to_string().contains("Timeout while downloading response body") => {
        tokio::time::sleep(Duration::from_secs(1)).await;
        http.request(req).await?
    }
    Err(e) => return Err(e.into()),
};
Defensive patterns

Strategy: retry

Validate before calling

// preflight: probe the endpoint with a short timeout before the real call
async fn reachable(url: &str) -> bool {
    reqwest::Client::new()
        .head(url)
        .timeout(Duration::from_secs(5))
        .send()
        .await
        .map(|r| r.status().is_success())
        .unwrap_or(false)
}

Try / catch

async fn request_with_retry(http: &Http, req: Request) -> Result<Response> {
    const MAX: usize = 3;
    for attempt in 1..=MAX {
        match http.request(req.clone()).await {
            Ok(r) => return Ok(r),
            Err(e) if e.to_string().contains("Timeout while downloading response body") && attempt < MAX => {
                tokio::time::sleep(Duration::from_millis(500 * attempt as u64)).await;
            }
            Err(e) => return Err(e.into()),
        }
    }
    unreachable!()
}

Prevention

When it happens

Trigger: WASM module issues an HTTP request whose response body never starts arriving within the timeout: server hangs after sending headers, network stalls, or a very slow/hung upstream behind a proxy.

Common situations: Backend service in the WASM app hangs (deadlocked DB query); firewall drops the connection silently after headers; huge slow upload on a poor mobile connection; proxy holding the response without streaming it.

Understand the failure class

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/ba47cccf1281a22a. Report an issue: GitHub.