dotnet/efcore · error · Exception
Failed to download {url} after {max_retries} attempts.
Error message
Failed to download {url} after {max_retries} attempts. What it means
Raised by download_file after all max_retries attempts (default 3) failed with transient network exceptions - asyncio.CancelledError, asyncio.TimeoutError, or aiohttp.ClientError. Note that an HTTP non-200 raises error 660 immediately and does not count toward these retries; this error is purely for connection/timeout level failures that never produced a usable response.
Source
Thrown at eng/common/cross/install-debs.py:47
# verify checksum if provided
if checksum:
sha256 = hashlib.sha256(content).hexdigest()
if sha256 != checksum:
raise Exception(f"SHA256 mismatch for {url}: expected {checksum}, got {sha256}")
f.write(content)
print(f"Downloaded {url} at {dest_path}")
return
else:
raise Exception(f"Failed to download {url}, Status Code: {response.status}")
except (asyncio.CancelledError, asyncio.TimeoutError, aiohttp.ClientError) as e:
print(f"Error downloading {url}: {type(e).__name__} - {e}. Retrying...")
attempt += 1
await asyncio.sleep(retry_delay)
raise Exception(f"Failed to download {url} after {max_retries} attempts.")
async def download_deb_files_parallel(mirror, packages, tmp_dir):
"""Download .deb files in parallel."""
os.makedirs(tmp_dir, exist_ok=True)
tasks = []
timeout = aiohttp.ClientTimeout(total=60)
async with aiohttp.ClientSession(timeout=timeout) as session:
for pkg, info in packages.items():
filename = info.get("Filename")
if filename:
url = f"{mirror}/{filename}"
dest_path = os.path.join(tmp_dir, os.path.basename(filename))
tasks.append(asyncio.create_task(download_file(session, url, dest_path, checksum=info.get("SHA256"))))
await asyncio.gather(*tasks)
async def download_package_index_parallel(mirror, arch, suites, check_sig, keyring):View on GitHub (pinned to dbf9771522)
Solutions
- Confirm basic connectivity to the mirror host: `curl -v <mirror>` / `getent hosts <mirror-host>`.
- Call download_file with larger timeout/max_retries/retry_delay arguments to tolerate slow links.
- Check proxy/ firewall settings and export http_proxy/https_proxy if a corporate proxy is required.
- Switch to a closer or more reliable mirror.
Example fix
# before
await download_file(session, url, dest_path, checksum=info.get("SHA256"))
# after
await download_file(session, url, dest_path, max_retries=5, retry_delay=5, timeout=180, checksum=info.get("SHA256")) Defensive patterns
Strategy: retry
Validate before calling
# Pre-flight reachability of the mirror host before the parallel downloads
import socket
def ensure_reachable(host, port=443):
try:
socket.gethostbyname(host)
with socket.create_connection((host, port), timeout=10):
return True
except OSError as e:
raise RuntimeError(f"Mirror host {host} unreachable: {e}; check DNS/proxy/firewall")
from urllib.parse import urlparse
h = urlparse(mirror).hostname
ensure_reachable(h) Try / catch
# Distinguish 'exhausted retries' from HTTP non-200 by message
try:
await download_file(session, url, dest_path, max_retries=5, retry_delay=5, timeout=180, checksum=checksum)
except Exception as e:
if "after" in str(e) and "attempts" in str(e):
# transient network failure - fall back to an alternate mirror
await download_file(session, alt_url_for(url), dest_path, max_retries=5, timeout=180, checksum=checksum)
else:
raise Prevention
- Pass larger max_retries/timeout for slow links; defaults (3 / 60s) are tight for big indexes.
- Export http_proxy/https_proxy in corporate networks so aiohttp can reach the mirror.
- Keep an alternate mirror configured so you can fall back instead of aborting.
When it happens
Trigger: Every retry attempt of session.get(url) raised a caught network exception: DNS resolution failure, TCP connect timeout, read timeout exceeding the aiohttp.ClientTimeout total, TLS handshake error, or connection reset. After max_retries the loop exits and raises.
Common situations: No internet or restricted network; corporate proxy/firewall blocking the mirror host; DNS misconfigured; the per-call timeout (default 60s) too short for a large Packages.gz or .deb over a slow link; mirror host temporarily unreachable.
Related errors
- SHA256 mismatch for {url}: expected {checksum}, got {sha256}
- Failed to download {url}, Status Code: {response.status}
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/91b0071959ece52a.
Report an issue: GitHub.