{"record":{"id":"82efd039d5052a9a","repo":"dotnet/efcore","slug":"could-not-find-checksum-for-path-in-release-file","errorCode":null,"errorMessage":"Could not find checksum for {path} in Release file.","messagePattern":"Could not find checksum for (.+?) in Release file\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"eng/common/cross/install-debs.py","lineNumber":154,"sourceCode":"\n        print(\"Signature verified successfully.\")\n\n        with open(release_file.name) as f:\n            return f.read()\n\ndef parse_release_file(content, path):\n    \"\"\"Parses the Release file and returns sha256 checksum of the specified path.\"\"\"\n\n    # data looks like this:\n    # <checksum>  <size>  <path>\n    matches = re.findall(r'^ (\\S*) +(\\S*) +(\\S*)$', content, re.MULTILINE)\n\n    for entry in matches:\n        # the file has both md5 and sha256 checksums, we want sha256 which has a length of 64\n        if entry[2] == path and len(entry[0]) == 64:\n            return entry[0]\n\n    raise Exception(f\"Could not find checksum for {path} in Release file.\")\n\ndef parse_debian_version(version):\n    \"\"\"Parse a Debian package version into epoch, upstream version, and revision.\"\"\"\n    match = re.match(r'^(?:(\\d+):)?([^-]+)(?:-(.+))?$', version)\n    if not match:\n        raise ValueError(f\"Invalid Debian version format: {version}\")\n    epoch, upstream, revision = match.groups()\n    return int(epoch) if epoch else 0, upstream, revision or \"\"\n\ndef compare_upstream_version(v1, v2):\n    \"\"\"Compare upstream or revision parts using Debian rules.\"\"\"\n    def tokenize(version):\n        tokens = re.split(r'([0-9]+|[A-Za-z]+)', version)\n        return [int(x) if x.isdigit() else x for x in tokens if x]\n\n    tokens1 = tokenize(v1)\n    tokens2 = tokenize(v2)\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/eng/common/cross/install-debs.py#L136-L172","documentation":"Raised by parse_release_file when scanning the Release file checksum lines (regex `^ (\\S*) +(\\S*) +(\\S*)$`) and finding no entry whose path equals the requested path AND whose first column is 64 chars (i.e. a SHA256). It means the Release file as fetched does not advertise a checksum for the Packages.gz path being verified.","triggerScenarios":"parse_release_file(content, path) is called with a path like 'main/binary-<arch>/Packages.gz' that does not appear in the Release file's checksum section - e.g. the component or architecture in the path is not published in that suite, or the suite's Release file uses a different filename (Packages.xz vs Packages.gz).","commonSituations":"--arch value not published by the suite (e.g. an arch only in ports but Release fetched from main debian); --suite that has no 'universe' component (Debian) but code requests both main and universe; mirror mixes suites incorrectly; Release file truncated so the matching line is missing.","solutions":["Fetch the Release file by hand (`curl <mirror>/dists/<suite>/Release`) and grep it for the path shown in {path} - confirm whether the component/arch/filename actually exist.","Correct --arch to match the suite's published architectures, and drop suites/components that the distro does not publish.","Use the right mirror variant (debian vs debian-ports) for the architecture.","Ensure the Release file downloaded fully (re-run; a truncated Release also triggers this)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Pre-check that the Release file lists the path you intend to fetch\nimport re, aiohttp, asyncio\n\nasync def release_has_path(mirror, suite, path):\n    async with aiohttp.ClientSession() as s:\n        async with s.get(f\"{mirror}/dists/{suite}/Release\") as r:\n            r.raise_for_status()\n            content = await r.text()\n    matches = re.findall(r'^ (\\S*) +(\\S*) +(\\S*)$', content, re.MULTILINE)\n    found = any(m[2] == path and len(m[0]) == 64 for m in matches)\n    if not found:\n        raise RuntimeError(f\"Release for {suite} has no sha256 for {path}; check arch/component/suite\")\n    return True\n\nasyncio.run(release_has_path(mirror, suite, f\"main/binary-{arch}/Packages.gz\"))","typeGuard":null,"tryCatchPattern":"try:\n    content = await download_package_index_parallel(mirror, arch, suites, check_sig=True, keyring=keyring)\nexcept Exception as e:\n    if \"Could not find checksum for\" in str(e):\n        # the path isn't published - stop probing other components and fix the args\n        raise SystemExit(f\"Suite {suites} does not publish the requested arch/component. {e}\")\n    raise","preventionTips":["Confirm the suite publishes your --arch (ports-only arches are not in main Debian).","Don't request components the distro lacks (Debian has no 'universe').","Cache and inspect the Release file once when adding a new suite/arch to the build."],"tags":["configuration","mirror","parsing","release-file"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}