pypa/pip · error · InstallationError

Unknown hash name

Error message

Unknown hash name: {hash_name}

What it means

Raised as InstallationError by Hashes.check_against_chunks when hashlib.new(hash_name) throws ValueError or TypeError, meaning the hash algorithm name specified in a requirement's --hash is not recognised by the system's hashlib. pip only allows algorithms listed in STRONG_HASHES (sha256, sha384, sha512) at the requirements-parsing layer, but this guard catches any that slip through or are computed at runtime. The error names the offending algorithm so the user can correct it.

Solutions

  1. Correct the algorithm name in the requirements file to one of sha256, sha384, or sha512.
  2. Regenerate the hash with `pip hash <file>` which always uses sha256.
  3. Remove the malformed --hash line entirely if you are not in --require-hashes mode.
  4. If a legitimate algorithm is rejected, verify your Python/OpenSSL build supports it with `python -c "import hashlib; hashlib.new('sha256')"`.

Example fix

// before
pkg==1.0 --hash=sha235:abc123...

// after
pkg==1.0 --hash=sha256:abc123...
Defensive patterns

Strategy: validation

Validate before calling

import hashlib

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

def validate_hash_lines(requirements_path: str) -> list[str]:
    """Return list of invalid --hash lines in a requirements file."""
    import re
    errors = []
    pattern = re.compile(r'--hash=([a-zA-Z0-9]+):')
    with open(requirements_path) as f:
        for i, line in enumerate(f, 1):
            for m in pattern.finditer(line):
                algo = m.group(1).lower()
                if algo not in VALID_HASH_NAMES:
                    errors.append(f'Line {i}: unknown hash algo {algo!r}')
    return errors

Type guard

def is_valid_hash_name(name: str) -> bool:
    """True if the hash algorithm is supported by pip's --hash."""
    return name.lower() in {'sha256', 'sha384', 'sha512'}

Prevention

When it happens

Trigger: A requirements file or pylock file containing a --hash line with a misspelled or unsupported algorithm name (e.g. `--hash=sha235:...`, `--hash=md5:...`). The loop at hashes.py:77-81 calls hashlib.new for each key in self._allowed and raises on failure.

Common situations: Typos in hash algorithm names in requirements files. Copying hashes generated by a tool that outputs non-strong algorithm names (md5, sha1). Manually editing requirements files and introducing a syntax error in the hash spec. Using a hash name valid on one platform but not another (e.g. OpenSSL-linked algorithms).

Related errors


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

Appendix: 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 f399c37189)