dotnet/aspnetcore · error · Exception
SHA256 mismatch for : expected , got
Error message
SHA256 mismatch for {path}: expected {packages_sha}, got {sha256} What it means
Raised by fetch_and_decompress when --force-check-gpg is set and the downloaded Packages.gz bytes hash to a different SHA256 than the value recorded in the Release file for that path. It guards the package index against mirror tampering or partial-publish drift, separate from the per-.deb check at error 345.
Solutions
- Switch --mirror to a known-consistent one (deb.debian.org or archive.ubuntu.com) and re-run.
- Drop corporate/transparent HTTP proxies that may serve stale cached bytes for Packages.gz while passing Release through fresh.
- Retry after a few minutes if the mirror is mid-publish; persistent mismatch indicates a real mirror bug worth reporting.
- Do not pass --force-check-gpg to silence it; that disables the entire chain of checks (348, 349, 350).
Example fix
# before python3 install-debs.py --mirror http://local-mirror/debian --suite trixie --arch amd64 \ --rootfsdir rootfs --force-check-gpg --keyring /usr/share/keyrings/debian-archive-keyring.gpg libc6 # 'SHA256 mismatch for main/binary-amd64/Packages.gz: expected ..., got ...' # after (canonical mirror, no proxy) unset http_proxy https_proxy python3 install-debs.py --mirror http://deb.debian.org/debian --suite trixie --arch amd64 \ --rootfsdir rootfs --force-check-gpg --keyring /usr/share/keyrings/debian-archive-keyring.gpg libc6
Defensive patterns
Strategy: validation
Validate before calling
# Compare the Release-file SHA256 for Packages.gz against the actual file before the run:
rel=$(curl -fsS "$MIRROR/dists/$SUITE/Release")
exp=$(printf '%s' "$rel" | awk -v p="main/binary-$ARCH/Packages.gz" '$1 ~ /^[0-9a-f]{64}$/ && $3==p {print $1}')
got=$(curl -fsS "$MIRROR/dists/$SUITE/main/binary-$ARCH/Packages.gz" | sha256sum | cut -d' ' -f1)
[ "$exp" = "$got" ] || { echo 'index/release drift; switch mirror'; exit 1; } Try / catch
try:
asyncio.run(download_package_index_parallel(mirror, arch, suites, True, keyring))
except Exception as e:
if 'SHA256 mismatch' in str(e) and 'Packages.gz' in str(e):
print('Release/Packages.gz drift from mirror; switch --mirror.')
raise Prevention
- Prefer canonical mirrors; avoid local caches that may serve inconsistent Release/Packages.gz.
- Disable transparent HTTP proxies during the run.
- Treat persistent mismatch as a mirror bug, not a script bug.
When it happens
Trigger: fetch_and_decompress computes hashlib.sha256(compressed_data) on the raw gzip bytes of Packages.gz and compares against packages_sha returned by parse_release_file(release_file_content, path). Any mismatch raises this Exception before the index is parsed.
Common situations: Mirror is mid-publish: Release file was updated but Packages.gz still serves the previous bytes (or vice versa); mirror snapshotted at an inconsistent point; transparent proxy cached an older Packages.gz against a newer Release; suite was renamed or pointed at a wrong components path; an attacker altered the index (rare; the gpg check at 349 would usually catch the Release tampering first).
Related errors
- SHA256 mismatch for : expected , got
- Signature verification failed
- Could not find checksum for
- Failed to download after attempts.
- Failed to download , Status Code
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/53239fb65f1d09d6.
Report an issue: GitHub.
Appendix: source
Thrown at eng/common/cross/install-debs.py:105
"""Fetch and decompress the Packages.gz file."""
path = f"{component}/binary-{arch}/Packages.gz"
url = f"{mirror}/dists/{suite}/{path}"
async with session.get(url) as response:
if response.status == 200:
compressed_data = await response.read()
decompressed_data = gzip.decompress(compressed_data).decode('utf-8')
print(f"Downloaded index: {url}")
if check_sig:
# Verify the package index against the sha256 recorded in the Release file
release_file_content = await fetch_release_file(session, mirror, suite, keyring)
packages_sha = parse_release_file(release_file_content, path)
sha256 = hashlib.sha256(compressed_data).hexdigest()
if sha256 != packages_sha:
raise Exception(f"SHA256 mismatch for {path}: expected {packages_sha}, got {sha256}")
print(f"Checksum verified for {path}")
return decompressed_data
else:
print(f"Skipped index: {url} (doesn't exist)")
return None
async def fetch_release_file(session, mirror, suite, keyring):
"""Fetch Release and Release.gpg files and verify the signature."""
release_url = f"{mirror}/dists/{suite}/Release"
release_gpg_url = f"{mirror}/dists/{suite}/Release.gpg"
with tempfile.NamedTemporaryFile() as release_file, tempfile.NamedTemporaryFile() as release_gpg_file:
await download_file(session, release_url, release_file.name)
await download_file(session, release_gpg_url, release_gpg_file.name)
print("Verifying signature of Release with Release.gpg.")View on GitHub (pinned to 3600ca084e)