dotnet/efcore · error · Exception
Failed to download after attempts.
Error message
Failed to download {url} after {max_retries} attempts. What it means
Raised by download_file after the while loop exhausts max_retries (default 3). It is only reached for the retryable exception types asyncio.CancelledError, asyncio.TimeoutError, and aiohttp.ClientError; integrity (620) and non-200 (621) failures bypass it. It is the terminal 'I retried and gave up' error for network-layer problems.
Solutions
- Check connectivity to the mirror: curl -I {mirror}.
- Increase timeout and retries by passing max_retries/timeout at the call site in download_deb_files_parallel (the CLI does not expose them).
- Switch to a closer/official mirror or a snapshot mirror.
- Fix DNS and HTTP_PROXY/HTTPS_PROXY environment.
- Reduce parallelism if the mirror is rate-limiting connections.
Example fix
// before
tasks.append(asyncio.create_task(download_file(session, url, dest_path, checksum=info.get("SHA256"))))
// after
tasks.append(asyncio.create_task(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
# preflight: basic reachability of the mirror before starting downloads
import urllib.request
try:
with urllib.request.urlopen(f"{mirror}/", timeout=10) as r:
assert r.status == 200
except Exception:
sys.exit("mirror unreachable, fix network/DNS/proxy before running") Try / catch
for run in range(3):
try:
asyncio.run(install_packages(...))
break
except Exception as e:
if "after" in str(e) and "attempts" in str(e):
continue # network exhaustion -> back off and retry the whole pipeline
raise
else:
raise SystemExit("downloads failed after repeated full-run retries") Prevention
- Run on a stable network link; configure HTTP_PROXY/HTTPS_PROXY correctly.
- Use a geo-local or official mirror to reduce timeouts.
- If on a slow link, raise the timeout/max_retries at the download_file call site.
When it happens
Trigger: Every attempt failed with a connection/timeout/DNS error (aiohttp.ClientError or asyncio.TimeoutError) for max_retries consecutive tries with retry_delay seconds between them.
Common situations: No or flaky network, mirror is down or rate-limiting, DNS misconfigured, firewall blocking the mirror, or the default 60s timeout is too short for a large .deb over a slow link.
Related errors
- Failed to download , Status Code
- SHA256 mismatch for : expected , got
- Could not find 'data.tar.*' in
- Unsupported compression format
- User transaction is not supported with a…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/91b0071959ece52a.
Report an issue: GitHub.
Appendix: 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 3a2006ef56)