Stirling-Tools/Stirling-PDF · critical · SystemExit

gitleaks checksum mismatch: expected {expected}, got {digest

Error message

gitleaks checksum mismatch: expected {expected}, got {digest}

What it means

SystemExit raised by install_gitleaks.main when the SHA256 digest of the downloaded gitleaks archive does not match the pinned expected checksum. This is a tamper/integrity check — a mismatch means the downloaded artifact differs from the vetted release (corruption, MITM, or a release that changed after pinning).

Source

Thrown at scripts/pre-commit/install_gitleaks.py:87

def main() -> int:
    if cached_version() == VERSION:
        return 0

    key = platform_key()
    expected = SHA256.get(key)
    if expected is None:
        raise SystemExit(f"No pinned gitleaks checksum for {key}")

    suffix = "zip" if key.startswith("windows") else "tar.gz"
    asset = f"gitleaks_{VERSION}_{key}.{suffix}"
    url = f"https://github.com/gitleaks/gitleaks/releases/download/v{VERSION}/{asset}"
    print(f"Downloading gitleaks {VERSION} ({asset})", flush=True)

    BIN.parent.mkdir(parents=True, exist_ok=True)
    archive, _ = urllib.request.urlretrieve(url)
    digest = hashlib.sha256(Path(archive).read_bytes()).hexdigest()
    if digest != expected:
        raise SystemExit(f"gitleaks checksum mismatch: expected {expected}, got {digest}")

    member = "gitleaks.exe" if IS_WINDOWS else "gitleaks"
    if suffix == "zip":
        with zipfile.ZipFile(archive) as zf:
            data = zf.read(member)
    else:
        with tarfile.open(archive) as tf:
            extracted = tf.extractfile(member)
            if extracted is None:
                raise SystemExit(f"{member} not found in {asset}")
            data = extracted.read()
    BIN.write_bytes(data)
    BIN.chmod(0o755)
    return 0


if __name__ == "__main__":
    sys.exit(main())

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Recompute the correct sha256 of the official release asset and update the SHA256 pin for the key.
  2. Re-download in case of transient corruption.
  3. Verify the VERSION and checksums come from the same gitleaks release notes.
  4. If intentional re-release, document it and update all affected platform pins.
Defensive patterns

Strategy: validation

Validate before calling

# Recompute and verify the checksum independently
import hashlib
digest = hashlib.sha256(Path(archive).read_bytes()).hexdigest()
assert digest == expected, f"checksum mismatch: expected {expected}, got {digest}"

Prevention

When it happens

Trigger: The downloaded archive's sha256 differs from the pinned value. Caused by: gitleaks re-published the release asset (force tag), a CDN/mirror served a different artifact, network corruption, or the pinned checksum is simply wrong/stale.

Common situations: The VERSION pin was updated but SHA256 pins were copied from the wrong release. A transient download corruption. gitleaks re-released under the same tag.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/1cf9725cd094d4fc. Report an issue: GitHub.