{"record":{"id":"d89f23457b163064","repo":"dotnet/runtime","slug":"sha256-mismatch-for-url-expected-checksum-go","errorCode":null,"errorMessage":"SHA256 mismatch for {url}: expected {checksum}, got {sha256}","messagePattern":"SHA256 mismatch for (.+?): expected (.+?), got (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"eng/common/cross/install-debs.py","lineNumber":34,"sourceCode":"\nfrom collections import deque\nfrom functools import cmp_to_key\n\nasync def download_file(session, url, dest_path, max_retries=3, retry_delay=2, timeout=60, checksum=None):\n    \"\"\"Asynchronous file download with retries.\"\"\"\n    attempt = 0\n    while attempt < max_retries:\n        try:\n            async with session.get(url, timeout=aiohttp.ClientTimeout(total=timeout)) as response:\n                if response.status == 200:\n                    with open(dest_path, \"wb\") as f:\n                        content = await response.read()\n\n                        # verify checksum if provided\n                        if checksum:\n                            sha256 = hashlib.sha256(content).hexdigest()\n                            if sha256 != checksum:\n                                raise Exception(f\"SHA256 mismatch for {url}: expected {checksum}, got {sha256}\")\n\n                        f.write(content)\n                    print(f\"Downloaded {url} at {dest_path}\")\n                    return\n                else:\n                    raise Exception(f\"Failed to download {url}, Status Code: {response.status}\")\n        except (asyncio.CancelledError, asyncio.TimeoutError, aiohttp.ClientError) as e:\n            print(f\"Error downloading {url}: {type(e).__name__} - {e}. Retrying...\")\n\n        attempt += 1\n        await asyncio.sleep(retry_delay)\n\n    raise Exception(f\"Failed to download {url} after {max_retries} attempts.\")\n\nasync def download_deb_files_parallel(mirror, packages, tmp_dir):\n    \"\"\"Download .deb files in parallel.\"\"\"\n    os.makedirs(tmp_dir, exist_ok=True)\n","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/eng/common/cross/install-debs.py#L16-L52","documentation":"install-debs.py computes the SHA-256 of downloaded .deb bytes and compares against the checksum recorded in the Packages index. A mismatch means the bytes received are not the bytes the mirror advertised - caused by a corrupt/partial download, a mirror out of sync, a transparent proxy/cache altering content, or (in the worst case) tampering. The script aborts rather than installing untrusted bytes into the rootfs.","triggerScenarios":"download_file fetches a .deb whose SHA256 differs from info['SHA256'] parsed from the Packages index. Raised at install-debs.py:33-34. Triggered by network corruption, a flaky mirror, a stale CDN edge, or a man-in-the-middle.","commonSituations":"Building a cross-arch rootfs behind a corporate HTTP proxy that rewrites responses. A Debian mirror mid-update (partial replication). A retry that landed on a different mirror with different content. Transient disk corruption in the temp download.","solutions":["Re-run the rootfs build; transient mirror/CDN desync usually clears within minutes.","Switch to a more up-to-date or official mirror via --mirror.","If behind a proxy, exclude the mirror domain from interception or use an internal mirror known to pass through bytes verbatim.","Clear the temp dir and let install-debs.py re-download from scratch."],"exampleFix":"# before\npython3 install-debs.py --arch arm64 --rootfsdir rootfs --suite bookworm --mirror http://bad-mirror/debian libc6\n# raises SHA256 mismatch\n\n# after\npython3 install-debs.py --arch arm64 --rootfsdir rootfs --suite bookworm --mirror http://deb.debian.org/debian libc6","handlingStrategy":"validation","validationCode":"# Pre-validate checksums you will pass to download_file by recomputing on a trusted copy.\nimport hashlib\ndef expected_sha256(path_or_url_known_good: bytes) -> str:\n    return hashlib.sha256(path_or_url_known_good).hexdigest()\n\n# Before installing: confirm your mirror serves byte-identical content by fetching\n# from a second trusted mirror and comparing SHA-256.","typeGuard":null,"tryCatchPattern":"# install-debs.py already retries via download_file; wrap the top-level call:\ntry:\n    main()\nexcept Exception as e:\n    if 'SHA256 mismatch' in str(e):\n        print('Mirror served bytes that disagree with the Packages index; try a different --mirror.')\n        sys.exit(2)\n    raise","preventionTips":["Use official mirrors that replicate atomically (deb.debian.org, ports mirror).","Exclude the Debian mirror from HTTP-proxy interception.","If checksums fail repeatedly, switch --mirror or wait for replication to settle."],"tags":["dotnet-rootfs","debian","download","sha256","integrity","python"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}