dotnet/efcore · error · Exception
Failed to download , Status Code
Error message
Failed to download {url}, Status Code: {response.status} What it means
Raised by download_file when the HTTP response status is anything other than 200. Like the SHA256 case it is a bare Exception, so it escapes the retry except clause and fails immediately: a 404/403/500 is NOT retried despite the retry loop.
Solutions
- Open {mirror}/{filename} in a browser or curl -I it to see the real status code and body.
- Confirm --mirror, --suite, and --arch form a valid combination (e.g. the arch exists for that suite).
- Try a different, official mirror.
- If the status is 5xx, wait and re-run the whole pipeline later.
- Check HTTP_PROXY/HTTPS_PROXY env vars are not routing to a broken proxy.
Example fix
// before
else:
raise Exception(f"Failed to download {url}, Status Code: {response.status}") # not retried
// after
else:
# raise a type the except clause covers so the retry loop actually engages
raise aiohttp.ClientError(f"HTTP {response.status} for {url}") Defensive patterns
Strategy: retry
Validate before calling
# preflight: HEAD one package URL to confirm the mirror serves it before the full run
import aiohttp
async def head_ok(mirror, filename):
async with aiohttp.ClientSession() as s:
async with s.get(f"{mirror}/{filename}") as r:
return r.status == 200
# if not asyncio.run(head_ok(args.mirror, sample_filename)): sys.exit('mirror cannot serve debs') Try / catch
try:
asyncio.run(download_deb_files_parallel(mirror, packages, tmp_dir))
except Exception as e:
if "Status Code" in str(e):
raise SystemExit(f"mirror returned non-200, check mirror/suite/arch: {e}")
raise Prevention
- Validate that --mirror, --suite, and --arch correspond to a published combination before running.
- Prefer official mirrors over community ones that may prune old packages.
- Clear HTTP_PROXY/HTTPS_PROXY if a proxy is rewriting responses.
When it happens
Trigger: session.get(url) returns a non-200 status for a .deb URL built as {mirror}/{info['Filename']}. Typical when the Packages index references a file path the mirror does not actually serve.
Common situations: --suite/--arch/--mirror mismatch (index from one suite, files from another), package removed from the suite, mirror temporarily returning 5xx, arch not published on that mirror, or a redirect to an HTML error page that aiohttp did not follow.
Related errors
- SHA256 mismatch for : expected , got
- Could not find 'data.tar.*' in
- Failed to download after attempts.
- Could not find checksum for
- SHA256 mismatch for : expected , got
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/437087a09524af21.
Report an issue: GitHub.
Appendix: source
Thrown at eng/common/cross/install-debs.py:40
attempt = 0
while attempt < max_retries:
try:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=timeout)) as response:
if response.status == 200:
with open(dest_path, "wb") as f:
content = await response.read()
# 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:View on GitHub (pinned to 3a2006ef56)