dotnet/aspnetcore · error · Exception

SHA256 mismatch for : expected , got

Error message

SHA256 mismatch for {url}: expected {checksum}, got {sha256}

What it means

Raised by install-debs.py download_file when the downloaded .deb file's SHA256 does not match the checksum recorded in the Packages index. It is a tamper/corruption guard: the bytes received from the mirror are not the bytes the package index attests to.

Solutions

  1. Retry against a different --mirror (e.g. switch from a local mirror to http://deb.debian.org/debian or http://archive.ubuntu.com/ubuntu) to rule out mirror drift.
  2. Disable any HTTP proxy (unset http_proxy/https_proxy) or bust the cache, then re-run.
  3. Confirm the --suite and --arch match the index you intend (mismatch yields a checksum from the wrong Packages.gz).
  4. If the mismatch is persistent and reproducible, file a mirror bug; do not weaken the check by removing the checksum argument.

Example fix

# before
python3 install-debs.py --mirror http://local-cache.example/debian --suite trixie --arch amd64 --rootfsdir rootfs libc6

# after (switch mirror, drop proxy)
unset http_proxy https_proxy
python3 install-debs.py --mirror http://deb.debian.org/debian --suite trixie --arch amd64 --rootfsdir rootfs libc6
Defensive patterns

Strategy: retry

Validate before calling

# Before invoking install-debs.py, sanity-check the mirror's index freshness:
curl -fsS --head "$MIRROR/dists/$SUITE/Release" | head -1
curl -fsS "$MIRROR/dists/$SUCE/Release" | grep -A2 '^SHA256:'
# Compare a sample .deb path's SHA256 between the index and the file; mismatch before the run => use another mirror.

Try / catch

try:
    asyncio.run(download_deb_files_parallel(mirror, packages, tmp))
except Exception as e:
    if 'SHA256 mismatch' in str(e):
        print('Mirror checksum drift; switch mirror and retry.')
        raise

Prevention

When it happens

Trigger: download_deb_files_parallel passes info.get("SHA256") from the parsed Packages index to download_file's checksum argument; the function hashes the response body and raises this Exception when hashlib.sha256(content).hexdigest() != checksum.

Common situations: Mirror partially updated (Packages index refreshed but .deb not yet synced, or vice versa); transparent HTTP proxy/corporate cache serving stale bytes; interrupted write where the connection was reset mid-stream but aiohttp returned a truncated body; a genuine MITM; package index for a different suite/arch than the .deb being fetched.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/8b2fea2ff9f79cc5. 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 3600ca084e)