dbt-labs/dbt-core · critical · RuntimeError

sha256 mismatch for {filename}: expected {entry['sha256']},

Error message

sha256 mismatch for {filename}: expected {entry['sha256']}, got {digest}

What it means

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.

Source

Thrown at crates/dbt-ci/templates/sdist_build_backend.py:104

            with urllib.request.urlopen(req, timeout=_TIMEOUT) as resp:
                return resp.read()
        except (urllib.error.URLError, TimeoutError, OSError) as exc:
            last = exc
            if attempt < _RETRIES:
                time.sleep(2 ** (attempt - 1))
    raise RuntimeError(f"failed to download {url}: {last}")


def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
    _emit_notice()
    entry = _select_wheel()
    filename = entry["filename"]
    url = "{base}/{file}".format(base=_MANIFEST["base_url"].rstrip("/"), file=filename)
    data = _fetch(url)

    digest = hashlib.sha256(data).hexdigest()
    if digest != entry["sha256"]:
        raise RuntimeError(
            f"sha256 mismatch for {filename}: expected {entry['sha256']}, got {digest}"
        )

    out = Path(wheel_directory) / filename
    out.write_bytes(data)
    return filename


def get_requires_for_build_wheel(config_settings=None):
    return []


def build_sdist(sdist_directory, config_settings=None):
    # The sdist is produced by `dbt-ci pypi pack --sdist`, not by this backend.
    raise RuntimeError(
        "this backend does not build sdists; use `dbt-ci pypi pack --sdist`"
    )

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Retry the install — a one-off corrupted transfer usually succeeds on a fresh download
  2. Clear proxy/CDN caches or bypass the proxy and download again
  3. 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`)
  4. If intentional tampering is suspected, investigate before trusting any mirror
  5. Pin to a release where asset and manifest digests agree

Example fix

# before: repackaged wheel without regenerating manifest
gh release upload mypkg-1.2.3-py3-none-mytag.whl  # overwrites asset
# after
dbt-ci pypi pack --sdist  # regenerates assets.json digests for republished assets
Defensive patterns

Strategy: validation

Validate before calling

import hashlib, json, urllib.request
manifest = json.loads(open('assets.json').read())
entry = next(iter(manifest['wheels'].values()))
data = urllib.request.urlopen(f"{manifest['base_url'].rstrip('/')}/{entry['filename']}").read()
assert hashlib.sha256(data).hexdigest() == entry['sha256'], 'asset/manifest digest mismatch — republish'

Type guard

def digest_matches(data: bytes, expected: str) -> bool:
    import hashlib
    return hashlib.sha256(data).hexdigest() == expected

Try / catch

try:
    build_wheel(wheel_dir)
except RuntimeError as e:
    if 'sha256 mismatch' in str(e):
        print('asset corrupted or republished; do NOT install; verify release integrity')
        raise SystemExit(1)
    raise

Prevention

When it happens

Trigger: `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.

Common situations: 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.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/24d597fcfe0c38cf. Report an issue: GitHub.