Skip to content

/flags/pip/pip-install-require-hashes

pip install --require-hashes: verify every package against a sha256 hash

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · pip 26.2.2 fromupdated
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

bash
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

RuleWhat happens otherwise
Every requirement pinned with ==Error: hashes require an exact version pin
Every requirement has --hashError listing the missing hashes
Dependencies are listed tooError: the unlisted dependency has no hash (or use --no-deps)
One hash per file that may be usedDifferent wheels per platform need one hash each
Editable installs (-e) are not allowedThey have no archive to hash

A hashed requirements file

text
# 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:

bash
pip-compile --generate-hashes requirements.in
uv pip compile --generate-hashes requirements.in -o requirements.txt

Pitfalls

  • 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-deps in 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.

Sources