denoland/deno · error
empty response from
Error message
empty response from {url} What it means
After the laufey archive download completes (including retries), the HTTP response body is empty: into_maybe_bytes() returned Ok(None), i.e. the server sent a 2xx response with zero bytes. The downloader treats an empty body as a hard error because it cannot even attempt the SHA-256 comparison on zero bytes.
Solutions
- Re-run the command — transient empty responses usually resolve on a fresh request.
- Verify the URL from the error with curl -IL to confirm the asset exists and has a non-zero Content-Length.
- Disable/inspect HTTP(S)_PROXY and NO_PROXY settings if a corporate proxy is in play, or exempt the release host.
- If it reproduces consistently, capture the exact URL and response headers and report it — a persistent empty 200 for a pinned asset is an upstream host problem.
Example fix
# before: opaque failure inside the tool deno desktop # error: empty response from https://.../laufey-v1.2.3-x86_64-unknown-linux-gnu.tar.gz # after: triage the URL out-of-band, then retry curl -IL 'https://.../laufey-v1.2.3-x86_64-unknown-linux-gnu.tar.gz' # expect 200 + Content-Length > 0 deno desktop
Defensive patterns
Strategy: retry
Validate before calling
# Probe the asset before launching the build; an empty/absent body shows up here
curl -fsSL -o /dev/null -w '%{http_code} %{size_download}\n' "$LAUFEY_ARCHIVE_URL"
# expect '200 <nonzero>'; anything else will fail inside deno too Try / catch
Catch download errors, inspect the context chain for 'empty response from', and retry with capped exponential backoff (2-3 attempts); an empty body from a CDN is overwhelmingly transient, unlike a checksum mismatch which must never be retried blindly.
Prevention
- Keep the release host reachable without a body-mangling proxy (NO_PROXY for the artifact host).
- Pre-warm/verify artifacts with a HEAD request in CI before invoking the desktop build.
- Log the URL (the code already includes it) so retries can be correlated to specific CDN nodes.
When it happens
Trigger: GET of the laufey release URL via download_with_progress_and_retries returns 204 No Content or a 200 with an empty body — e.g. a misbehaving mirror, a corporate proxy that swallows the body, a redirect chain ending in an empty object store response, or a transient CDN failure after the final retry succeeded at the header level.
Common situations: Corporate HTTP(S) proxies or SSL-inspecting middleboxes that return empty bodies; a truncated object-storage response on a flaky connection; the release asset was yanked and the host now serves an empty 200; rare transient CDN glitch.
Related errors
- checksum mismatch for
- Either `node` or `range` must be provided when reporting an…
- fetch failed
- TLS wrap attach (JS stream) failed
- ${bindingName} ${errCodeMessage} ${name}
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/367c21b4890e6abb.
Report an issue: GitHub.
Appendix: source
Thrown at cli/tools/desktop.rs:1986
let url = Url::parse(&laufey_release_url(&archive))?;
let progress_bar = ProgressBar::new(ProgressBarStyle::DownloadBars);
let progress = progress_bar.update(&archive);
// Send a real User-Agent — some CDNs (incl. parts of GitHub
// releases) start rate-limiting empty UAs aggressively.
let mut headers = http::HeaderMap::new();
if let Ok(ua) = http::HeaderValue::from_str(&format!(
"deno-desktop/{} (+https://deno.com)",
env!("CARGO_PKG_VERSION")
)) {
headers.insert(http::header::USER_AGENT, ua);
}
let response = client
.download_with_progress_and_retries(url.clone(), &headers, &progress)
.await
.with_context(|| format!("failed to download {url}"))?;
let data = response
.into_maybe_bytes()?
.ok_or_else(|| deno_core::anyhow::anyhow!("empty response from {url}"))?;
let actual =
faster_hex::hex_string(&sha2::Sha256::digest(&data)).to_lowercase();
let expected_lc = expected.to_lowercase();
if actual != expected_lc {
// Include the URL in the bail: an attacker who poisoned a redirect
// would otherwise be invisible in the failure log.
bail!(
"checksum mismatch for {archive} (downloaded from {url})\n expected: {expected_lc}\n actual: {actual}"
);
}
let parent = dir.parent().ok_or_else(|| {
deno_core::anyhow::anyhow!(
"LAUFEY cache dir has no parent: {}",
dir.display()
)
})?;View on GitHub (pinned to f7822238ca)