{"record":{"id":"24d597fcfe0c38cf","repo":"dbt-labs/dbt-core","slug":"sha256-mismatch-for-filename-expected-entry-s","errorCode":null,"errorMessage":"sha256 mismatch for {filename}: expected {entry['sha256']}, got {digest}","messagePattern":"sha256 mismatch for (.+?): expected (.+?), got (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"crates/dbt-ci/templates/sdist_build_backend.py","lineNumber":104,"sourceCode":"            with urllib.request.urlopen(req, timeout=_TIMEOUT) as resp:\n                return resp.read()\n        except (urllib.error.URLError, TimeoutError, OSError) as exc:\n            last = exc\n            if attempt < _RETRIES:\n                time.sleep(2 ** (attempt - 1))\n    raise RuntimeError(f\"failed to download {url}: {last}\")\n\n\ndef build_wheel(wheel_directory, config_settings=None, metadata_directory=None):\n    _emit_notice()\n    entry = _select_wheel()\n    filename = entry[\"filename\"]\n    url = \"{base}/{file}\".format(base=_MANIFEST[\"base_url\"].rstrip(\"/\"), file=filename)\n    data = _fetch(url)\n\n    digest = hashlib.sha256(data).hexdigest()\n    if digest != entry[\"sha256\"]:\n        raise RuntimeError(\n            f\"sha256 mismatch for {filename}: expected {entry['sha256']}, got {digest}\"\n        )\n\n    out = Path(wheel_directory) / filename\n    out.write_bytes(data)\n    return filename\n\n\ndef get_requires_for_build_wheel(config_settings=None):\n    return []\n\n\ndef build_sdist(sdist_directory, config_settings=None):\n    # The sdist is produced by `dbt-ci pypi pack --sdist`, not by this backend.\n    raise RuntimeError(\n        \"this backend does not build sdists; use `dbt-ci pypi pack --sdist`\"\n    )\n","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-ci/templates/sdist_build_backend.py#L86-L122","documentation":"After downloading the prebuilt wheel, `build_wheel` computes its sha256 and compares it to the digest embedded in the sdist's `assets.json`. A mismatch means the bytes fetched are not the bytes the release was packed with — so instead of installing a corrupted or tampered wheel, the backend aborts with RuntimeError.","triggerScenarios":"`build_wheel` successfully downloads `{base_url}/{filename}` via `_fetch`, but `hashlib.sha256(data).hexdigest()` differs from `entry['sha256']` in assets.json — i.e. the downloaded artifact does not match the recorded digest.","commonSituations":"A corrupted or truncated download behind a misbehaving proxy; the release asset was overwritten/re-uploaded with different content (version repack) while the sdist still carries the old digest; a CDN serving a stale or wrong object; man-in-the-middle tampering.","solutions":["Retry the install — a one-off corrupted transfer usually succeeds on a fresh download","Clear proxy/CDN caches or bypass the proxy and download again","Verify the published asset's actual sha256 against the manifest; if the asset was re-uploaded, republish the sdist with a regenerated assets.json (`dbt-ci pypi pack`)","If intentional tampering is suspected, investigate before trusting any mirror","Pin to a release where asset and manifest digests agree"],"exampleFix":"# before: repackaged wheel without regenerating manifest\ngh release upload mypkg-1.2.3-py3-none-mytag.whl  # overwrites asset\n# after\ndbt-ci pypi pack --sdist  # regenerates assets.json digests for republished assets","handlingStrategy":"validation","validationCode":"import hashlib, json, urllib.request\nmanifest = json.loads(open('assets.json').read())\nentry = next(iter(manifest['wheels'].values()))\ndata = urllib.request.urlopen(f\"{manifest['base_url'].rstrip('/')}/{entry['filename']}\").read()\nassert hashlib.sha256(data).hexdigest() == entry['sha256'], 'asset/manifest digest mismatch — republish'","typeGuard":"def digest_matches(data: bytes, expected: str) -> bool:\n    import hashlib\n    return hashlib.sha256(data).hexdigest() == expected","tryCatchPattern":"try:\n    build_wheel(wheel_dir)\nexcept RuntimeError as e:\n    if 'sha256 mismatch' in str(e):\n        print('asset corrupted or republished; do NOT install; verify release integrity')\n        raise SystemExit(1)\n    raise","preventionTips":["Never re-upload release assets with changed content; republish a new version with regenerated assets.json","Verify published asset digests as part of release CI","Avoid intercepting proxies that can corrupt large binary downloads","Treat any mismatch as a supply-chain red flag and investigate before retrying blindly"],"tags":["security","checksum","sha256","supply-chain"],"backgroundTag":"checksum-mismatch","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}