dotnet/runtime · error · Exception
Failed to download {url}, Status Code: {response.status}
Error message
Failed to download {url}, Status Code: {response.status} What it means
download_file received an HTTP response with a status code other than 200 (e.g. 404 Not Found, 403 Forbidden, 500/502/503 server error). The exception captures the status so the caller can see why the .deb or Release file could not be fetched. The function then retries up to max_retries before giving up.
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 60108ba66e)
Solutions
- Verify --arch and --suite match a mirror layout that actually contains the package (browse the mirror's dists/<suite>/ directory).
- Switch to a mirror that still hosts the package, or pick a newer --suite.
- If 4xx is intermittent (rate limit/CDN), wait and retry; for 5xx pick a different mirror.
- Make sure the base-packages list (dpkg, busybox, libc6, etc.) is available on the chosen mirror.
Example fix
# before python3 install-debs.py --arch loong64 --suite sid --mirror http://deb.debian.org/debian libc6 # 404: sid does not carry loong64 at deb.debian.org # after python3 install-debs.py --arch loong64 --suite sid --mirror http://ftp.ports.debian.org/debian-ports libc6
Defensive patterns
Strategy: retry
Validate before calling
# Pre-flight: probe a HEAD request for each .deb URL before the build.
import aiohttp, asyncio
async def probe(url: str) -> int:
async with aiohttp.ClientSession() as s:
async with s.head(url) as r:
return r.status
# If status != 200, fix --arch/--suite/--mirror before running install-debs.py. Try / catch
# download_file already retries 3x. For 4xx, fix the mirror/suite/arch instead of retrying:
try:
main()
except Exception as e:
if 'Status Code: 40' in str(e):
print('Package path not found; check --arch/--suite/--mirror.')
sys.exit(2)
raise Prevention
- Verify --arch and --suite against the mirror's dists/ layout before building.
- Use official mirrors that still host the chosen suite.
- HEAD-probe each .deb URL in CI before the full rootfs build.
When it happens
Trigger: Fetching a .deb by the path stored in the Packages index, but the mirror returns 404 (package retired, suite changed, arch mismatch). Or a 403/5xx due to mirror problems. Raised at install-debs.py:40 inside the retry loop.
Common situations: Pointing --suite at a released Debian/Ubuntu version where a package was removed. Wrong --arch (e.g. arm64 against an amd64-only mirror). Mirror rate-limiting returning 403. Mirror maintenance returning 5xx.
Related errors
- Failed to download {url} after {max_retries} attempts.
- SHA256 mismatch for {url}: expected {checksum}, got {sha256}
- SHA256 mismatch for {path}: expected {packages_sha}, got {sh
- Signature verification failed: {result.stderr.decode('utf-8'
- Could not find checksum for {path} in Release file.
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/8c3c59b871ce1355.
Report an issue: GitHub.