dotnet/efcore · error · Exception
SHA256 mismatch for : expected , got
Error message
SHA256 mismatch for {url}: expected {checksum}, got {sha256} What it means
Raised by download_file when a caller-supplied checksum (the SHA256 from the Packages index, passed at line 61) does not match the SHA256 of the bytes actually received from the mirror. It signals a corrupted or substituted download. Note the exception is a bare Exception, so it is NOT one of the retryable types in the except tuple (CancelledError/TimeoutError/ClientError) and propagates immediately without retry.
Solutions
- Re-run against a different mirror (e.g. switch from a community mirror to the official one) since the most common cause is a mirror mid-publish.
- Verify --mirror, --suite, and --arch are a consistent, valid combination.
- Manually curl the failing {url}, compute sha256sum, and compare against the SHA256 field in the Packages index to confirm whether the mirror or the index is wrong.
- Disable any transparent HTTP proxy (HTTP_PROXY/HTTPS_PROXY, apt-cacher) and retry.
- If reproducible across mirrors, treat it as a potential integrity attack and investigate the source of the bytes.
Example fix
// before
if sha256 != checksum:
raise Exception(f"SHA256 mismatch for {url}: expected {checksum}, got {sha256}") # propagates, NOT retried
// after
if sha256 != checksum:
raise aiohttp.ClientError(f"SHA256 mismatch for {url}: expected {checksum}, got {sha256}") # now caught by the retry handler Defensive patterns
Strategy: retry
Validate before calling
# preflight: confirm the mirror serves the expected bytes for one sample package
import aiohttp, asyncio, hashlib
async def verify(mirror, filename, expected):
async with aiohttp.ClientSession() as s:
async with s.get(f"{mirror}/{filename}") as r:
data = await r.read()
return hashlib.sha256(data).hexdigest() == expected
# asyncio.run(verify(args.mirror, sample_filename, sample_sha)) Try / catch
try:
asyncio.run(download_package_index_parallel(...))
asyncio.run(install_packages(...))
except Exception as e:
if "SHA256 mismatch" in str(e):
# integrity failure -> retry against a different trusted mirror, do NOT silently continue
raise SystemExit(f"integrity failure, retry with another mirror: {e}")
raise Prevention
- Pin --mirror to an official archive or a dated snapshot mirror so Release and Packages stay consistent.
- Keep --force-check-gpg on so index integrity is verified before any .deb is trusted.
- Disable transparent HTTP caches (apt-cacher, corporate proxies) that can serve stale .deb bytes.
When it happens
Trigger: Calling download_file with checksum set (as download_deb_files_parallel does via info.get('SHA256')) and the body returned by {mirror}/{filename} hashes to a different value than the Packages index recorded.
Common situations: Mirror is mid-sync (inconsistent build published), CDN/cache serves a stale or different build, --mirror and --suite point to inconsistent sources, a corporate proxy or apt-cacher serves cached wrong bytes, or (rarely) a MITM altering bytes.
Related errors
- Failed to download , Status Code
- SHA256 mismatch for : expected , got
- Could not find 'data.tar.*' in
- Failed to download after attempts.
- Could not find checksum for
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/b0270b0a48fd1da3.
Report an issue: GitHub.
Appendix: source
Thrown at eng/common/cross/install-debs.py:34
from collections import deque
from functools import cmp_to_key
async def download_file(session, url, dest_path, max_retries=3, retry_delay=2, timeout=60, checksum=None):
"""Asynchronous file download with retries."""
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)
View on GitHub (pinned to 3a2006ef56)