pypa/pip · error · HashMismatch
THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS
Error message
THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
What it means
HashMismatch (the headline 'THESE PACKAGES DO NOT MATCH THE HASHES...') raised by _raise() when none of the computed digests of the downloaded archive match any allowed digest in the requirements file. It signals either a legitimate version drift (hashes not refreshed after a version bump) or, worst case, a tampered/MITM'd artifact.
Source
Thrown at src/pip/_internal/utils/hashes.py:93
"""
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.
"""
return self.check_against_chunks(read_chunks(file))
def check_against_path(self, path: str) -> None:
with open(path, "rb") as file:
return self.check_against_file(file)
def has_one_of(self, hashes: Mapping[str, str]) -> bool:
"""Return whether any of the given hashes are allowed."""
for hash_name, hex_digest in hashes.items():
if self.is_hash_allowed(hash_name, hex_digest):
return TrueView on GitHub (pinned to d7d0d0a394)
Solutions
- If you intentionally changed versions, regenerate hashes with `pip hash <file>` or pip-compile and update the requirements file.
- Verify the downloaded archive against the publisher's official checksum before trusting new hashes.
- Clear pip's cache (pip cache purge) and the mirror cache to rule out a stale/corrupt cached file.
- If you did not change anything, treat as a possible tamper: do NOT just update the hash — investigate the source.
Example fix
# before pkg==1.0 --hash=sha256:OLDHASH... # (you bumped to 1.1 but left the 1.0 hash) # after - regenerate for the actual archive pip download pkg==1.1 --no-deps -d /tmp/p pip hash /tmp/p/pkg-1.1*.whl # paste output back into requirements.txt
Defensive patterns
Strategy: validation
Validate before calling
import hashlib
def verify_archive_hash(path, expected_alg, expected_hex):
h = hashlib.new(expected_alg)
with open(path, 'rb') as f:
for chunk in iter(lambda: f.read(1 << 16), b''):
h.update(chunk)
if h.hexdigest() != expected_hex:
raise ValueError(f"{expected_alg} mismatch for {path}")
# run before pip if you pre-download archives; never auto-update on mismatch without trust review Try / catch
try:
pip_install('-r', 'reqs.txt')
except HashMismatch as e:
# only safe to auto-refresh if you intentionally changed versions
if versions_intentionally_bumped('reqs.txt'):
regenerate_hashes('reqs.txt')
pip_install('-r', 'reqs.txt')
else:
raise # possible tamper — do NOT paper over it Prevention
- Regenerate hashes with pip-compile/pip hash whenever you change a version.
- Verify downloaded files against upstream-published checksums.
- Purge pip cache and mirror caches if mismatches appear unexpectedly.
When it happens
Trigger: check_against_chunks computes gots for each allowed algorithm and none of got.hexdigest() values appear in self._allowed[hash_name]. Happens after download when --require-hashes is on or any requirement carries --hash and the archive bytes don't match.
Common situations: Bumped a version in requirements.txt but forgot to re-run pip-compile/hash; a mirror serving a cached-but-different file; a corporate proxy re-packaging wheels; an actual supply-chain attack; cross-posting a file that was re-uploaded in place.
Related errors
- Unknown hash name: {hash_name}
- Hashes are required in --require-hashes mode, but they are m
- Can't verify hashes for these requirements because we don't
- Can't verify hashes for these file:// requirements because t
- In --require-hashes mode, all requirements must have their v
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/563e730230e25926.json.
Report an issue: GitHub.