pypa/pip · error · HashMissing
Hashes are required in --require-hashes mode, but they are…
Error message
Hashes are required in --require-hashes mode, but they are missing from some requirements. Here is a list of those requirements along with the hashes their downloaded archives actually had. Add lines like these to your requirements files to prevent tampering. (If you did not enable --require-hashes manually, note that it turns on automatically when any package has a hash.)
What it means
Raised as HashMissing by MissingHashes._raise (hashes.py:150) when --require-hashes mode is active (either explicitly or auto-enabled because another package has a hash) and a requirement has no hash specified at all. MissingHashes is initialised with an empty allowed-list for sha256 so the check always fails, then _raise outputs the actual computed hash so the user can copy it into their requirements file. The message instructs the user to add the missing --hash lines.
Solutions
- Copy the hash lines that pip prints in the error message and paste them into your requirements file for the affected package(s).
- Run `pip install --require-hashes --dry-run -r requirements.txt` (or pip hash) to pre-compute hashes for all packages.
- Regenerate the entire lock file with hashes using `pip freeze --all` or a tool like pip-tools (`pip-compile --generate-hashes`).
- If you did not intend hash-locked mode, remove all --hash entries from your requirements file to disable auto-enabling.
Example fix
// before package-a==1.0 --hash=sha256:abc... package-b==2.0 // after package-a==1.0 --hash=sha256:abc... package-b==2.0 --hash=sha256:def... (from error output)
Defensive patterns
Strategy: validation
Validate before calling
import re
def find_requirements_without_hashes(path: str) -> list[str]:
"""Return package specs that lack a --hash in a requirements file."""
missing = []
with open(path) as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
if '==' in line and '--hash=' not in line:
missing.append(line)
return missing
# Run before pip install --require-hashes Try / catch
from pip._internal.exceptions import HashMissing
try:
# pip install --require-hashes operation
pass
except HashMissing as e:
# e.hash_value contains the computed hash to add
print(f'Add this hash: sha256:{e.hash_value}') Prevention
- Use pip-compile --generate-hashes to produce fully-hashed lock files.
- Audit lock files for any package spec lacking a --hash before enabling --require-hashes.
- Remember: adding a hash to ANY package auto-enables require-hashes for all packages.
When it happens
Trigger: Running pip install with --require-hashes where at least one requirement lacks a --hash entry. Also triggers automatically when any single requirement in the file has a hash: pip turns on require-hashes globally (hashes.py:147), and MissingHashes is used for the requirement without one. _raise at line 150 fires after the download completes and the computed sha256 doesn't match the empty allowed list.
Common situations: Enabling --require-hashes but forgetting to add hashes for some requirements. Adding a hash to one package which auto-enables hash checking for all dependencies, catching the ones without hashes. New transitive dependencies introduced by a version bump that lack hashes.
Related errors
- THESE PACKAGES DO NOT MATCH THE HASHES FROM THE…
- Unknown hash name
- Algorithm used in hash field has different value in hashes…
- Algorithm used in hash field is not present in hashes field
- At least one hash must be provided
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/bb5e8787fab7ac84.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/utils/hashes.py:150
)
class MissingHashes(Hashes):
"""A workalike for Hashes used when we're missing a hash for a requirement
It computes the actual hash of the requirement and raises a HashMissing
exception showing it to the user.
"""
def __init__(self) -> None:
"""Don't offer the ``hashes`` kwarg."""
# Pass our favorite hash in to generate a "gotten hash". With the
# empty list, it will never match, so an error will always raise.
super().__init__(hashes={FAVORITE_HASH: []})
def _raise(self, gots: dict[str, _Hash]) -> NoReturn:
raise HashMissing(gots[FAVORITE_HASH].hexdigest())
View on GitHub (pinned to f399c37189)