Hash checking mode makes pip verify each downloaded file against a sha256 hash you wrote into requirements.txt, and refuse the install on any mismatch. It protects against remote tampering and network issues. It turns on globally as soon as one requirement carries a hash, and it needs every requirement pinned.
What pip documents
Hash checking was added in pip 8.0. The pip documentation says it uses local hashes embedded in a requirements file to protect against remote tampering and network issues. Hashes are given with a hash option per requirement, and it is all or nothing: adding a hash to any requirement activates the mode for the whole install.
Restrictions from the docs:
| Rule | Reason given |
|---|---|
| Hashes required for all requirements | A partly hashed file lets bad code slip in through the unhashed entries |
| Hashes required for all dependencies | An unlisted dependency causes an error |
| Requirements must be pinned with == or a URL or path | A new matching version would cause a surprise mismatch |
pip also documents a way to force the mode, and a newer option in version 26.2 to disable automatic enforcement when only some requirements carry hashes, in which case only those are verified. Use that only for a reason, such as local directories.
Example
FooProject==1.2 \
--hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 \
--hash=sha256:486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7
Several hashes per package let both a wheel and a source archive pass. The pip hash command prints a hash for a downloaded file.
Steps to adopt it
- Pin every dependency, including transitive ones, with a resolver or lock tool that can write hashes.
- Generate hashes for each file you accept, wheels and any source archive.
- Install in CI with hash enforcement forced, so a missing hash fails the job.
- Pair it with a rule that only binary wheels are installed if you want to avoid build time code execution from source archives. pip's secure installs page lists disallowing source distributions as a second measure.
- Review hash changes in pull requests as you would version changes.
What it does not do
A hash proves the file is the one you recorded. It does not prove the recorded file is benign. If the first hash was taken from a malicious release, the check will pass. Combine it with vulnerability and malware scanning at the time you add or update a pin. For wider context see what package provenance proves.
Safeguard's SBOM and dependency scanning evaluates pinned Python requirements for known vulnerabilities on each change.
Quick check
Can I hash only some requirements?
By default, no. Once one requirement has a hash, hashes are required for all. A flag in pip 26.2 can relax this, so only hashed items are verified.
Do I need to pin versions?
Yes. Requirements must be pinned to an exact version, URL or path so a new release does not cause a surprise mismatch.
Sources
Last reviewed: 19 October 2026.