/flags/pip/pip-install-require-hashes
pip install --require-hashes: verify every package against a sha256 hash
- tool
- pip
- command
- pip install, pip download
- flag
- --require-hashes
- default
- off (hash-checking turns on automatically when any requirement has --hash)
pip install --require-hashes -r requirements.txt refuses to install anything unless every requirement is pinned with == and carries at least one --hash=sha256:... value, and it checks each downloaded file against those hashes. A changed or tampered archive on the index then fails the install instead of being executed. It is pip's built-in protection against supply-chain attacks and accidental drift. pip download uses the same checks, so the examples run with it.
Missing, correct and wrong hashes
echo "six==1.16.0" > requirements.txt
echo "--- no hash in the file"
pip download --disable-pip-version-check --require-hashes -d dl -r requirements.txt 2>&1 | grep -E "^ERROR|--hash" | tee hashes.txt
sed -E 's/^ +//' hashes.txt | grep -- "--hash" > requirements.txt
echo "--- with the hash pip reported"
pip download --disable-pip-version-check -q --require-hashes -d dl -r requirements.txt; echo "exit: $?"
echo "--- with a wrong hash"
echo "six==1.16.0 --hash=sha256:0000000000000000000000000000000000000000000000000000000000000000" > requirements.txt
rm -rf dl
pip download --disable-pip-version-check --require-hashes -d dl -r requirements.txt 2>&1 | grep -E "^ERROR|DO NOT MATCH"Output
--- no hash in the file
ERROR: 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.)
six==1.16.0 --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
--- with the hash pip reported
exit: 0
--- with a wrong hash
ERROR: 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.The first error is helpful: pip prints the requirement with the hash of the file it just downloaded, ready to paste. With that line in the file the download passes; with a different hash pip stops with the THESE PACKAGES DO NOT MATCH THE HASHES error.
Rules in hash-checking mode
| Rule | What happens otherwise |
|---|---|
| Every requirement pinned with == | Error: hashes require an exact version pin |
| Every requirement has --hash | Error listing the missing hashes |
| Dependencies are listed too | Error: the unlisted dependency has no hash (or use --no-deps) |
| One hash per file that may be used | Different wheels per platform need one hash each |
| Editable installs (-e) are not allowed | They have no archive to hash |
A hashed requirements file
# placeholders: the real values are 64 hexadecimal characters
requests==2.32.3 \
--hash=sha256:<sha256 of the wheel>
idna==3.10 \
--hash=sha256:<sha256 of the wheel>Tools write this format for you, with one hash per wheel and sdist so the file works on every platform:
pip-compile --generate-hashes requirements.in
uv pip compile --generate-hashes requirements.in -o requirements.txtPitfalls
- Hashes protect the files, not the choice of versions. Review what the lock tool resolved; a malicious version that is hashed is still malicious.
- A file generated on Linux with only the Linux wheel hash fails on Windows or macOS, where pip picks another wheel. Generate hashes for all platforms.
pip install .for a local project in hash-checking mode fails because the local directory has no hash; install the project with--no-depsin a separate call. See pip install --no-deps.- The file must still be readable and syntactically valid: see Could not open requirements file and Invalid requirement.
FAQ
How do I generate a requirements file with hashes?
Use pip-compile --generate-hashes (pip-tools) or uv pip compile --generate-hashes. For a single file, pip hash FILE prints the --hash=sha256:... value of a downloaded archive.
Do I need --require-hashes if the file already contains hashes?
No. As soon as any requirement has a --hash option, pip switches to hash-checking mode for the whole install. The flag makes that mode mandatory, so a file without hashes fails instead of installing unchecked.
Why does pip say the hashes do not match after a new release?
The pin is missing or not exact (==), so pip picked a newer file whose hash is not listed. In hash-checking mode every requirement must be pinned with == and every file pip might use must have its hash listed.