pypa/pip · error · InstallationError

Unknown hash name: {hash_name}

Error message

Unknown hash name: {hash_name}

What it means

InstallationError raised in Hashes.check_against_chunks when hashlib.new(hash_name) throws ValueError/TypeError — the hash algorithm name supplied via --hash (or in a requirements file) is not recognized by hashlib. Only names in STRONG_HASHES (sha256/sha384/sha512) are intended, but any hashlib-unknown string triggers this at verify time.

Source

Thrown at src/pip/_internal/utils/hashes.py:81

        return sum(len(digests) for digests in self._allowed.values())

    def is_hash_allowed(self, hash_name: str, hex_digest: str) -> bool:
        """Return whether the given hex digest is allowed."""
        return hex_digest in self._allowed.get(hash_name, [])

    def check_against_chunks(self, chunks: Iterable[bytes]) -> None:
        """Check good hashes against ones built from iterable of chunks of
        data.

        Raise HashMismatch if none match.

        """
        gots = {}
        for hash_name in self._allowed.keys():
            try:
                gots[hash_name] = hashlib.new(hash_name)
            except (ValueError, TypeError):
                raise InstallationError(f"Unknown hash name: {hash_name}")

        for chunk in chunks:
            for hash in gots.values():
                hash.update(chunk)

        for hash_name, got in gots.items():
            if got.hexdigest() in self._allowed[hash_name]:
                return
        self._raise(gots)

    def _raise(self, gots: dict[str, _Hash]) -> NoReturn:
        raise HashMismatch(self._allowed, gots)

    def check_against_file(self, file: BinaryIO) -> None:
        """Check good hashes against a file-like object

        Raise HashMismatch if none match.

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Regenerate hashes with `pip hash` or pip-compile using sha256 (the FAVORITE_HASH).
  2. Replace md5/sha1 hashes with sha256 hashes of the same archives.
  3. Fix typos/casing in the algorithm name (use lowercase sha256/sha384/sha512).

Example fix

# before
pkg==1.0 --hash=md5:abcdef...

# after
pkg==1.0 --hash=sha256:$(curl -sL https://files/pythonhosted.org/.../pkg-1.0.tar.gz | sha256sum | cut -d' ' -f1)
Defensive patterns

Strategy: validation

Validate before calling

import hashlib

ALLOWED = {'sha256', 'sha384', 'sha512'}

def validate_hash_names(req_hashes):
    for alg in req_hashes:
        if alg not in ALLOWED:
            try:
                hashlib.new(alg)
            except (ValueError, TypeError) as e:
                raise ValueError(f"unsupported/typo hash algorithm {alg!r}: {e}")
# run over a requirements file's --hash keys before installing

Try / catch

try:
    pip_install('-r', 'reqs.txt')
except InstallationError as e:
    if 'Unknown hash name' in str(e):
        normalize_hash_algorithms('reqs.txt')  # rewrite md5/sha1 → sha256
        pip_install('-r', 'reqs.txt')
    else:
        raise

Prevention

When it happens

Trigger: self._allowed contains a key that hashlib.new() rejects. E.g. a requirements line `pkg --hash=md5:...` or `--hash=sha1:...`, or a typo like `--hash=SHA256:...` handled case-sensitively, or a junk algorithm name.

Common situations: Copying hashes from an old lockfile that used md5/sha1; an external tool (pip-tools/pip-compile older version) emitting a weak algorithm; a hand-typed algorithm name typo; a requirements fragment produced by a non-pip hasher.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/7f37f36845a64453.json. Report an issue: GitHub.