pypa/pip · error · DirectoryUrlHashUnsupported
Can't verify hashes for these file:// requirements because t
Error message
Can't verify hashes for these file:// requirements because they point to directories:
What it means
Raised as DirectoryUrlHashUnsupported when --require-hashes is active and a requirement points to a local directory via a file:// URL or an existing-directory link. At prepare.py:475-476, _get_linked_req_hashes checks req.link.is_existing_dir() and aborts because a directory has no single file to hash.
Source
Thrown at src/pip/_internal/operations/prepare.py:476
req.ensure_pristine_source_checkout()
def _get_linked_req_hashes(self, req: InstallRequirement) -> Hashes:
# By the time this is called, the requirement's link should have
# been checked so we can tell what kind of requirements req is
# and raise some more informative errors than otherwise.
# (For example, we can raise VcsHashUnsupported for a VCS URL
# rather than HashMissing.)
if not self.require_hashes:
return req.hashes(trust_internet=True)
# We could check these first 2 conditions inside unpack_url
# and save repetition of conditions, but then we would
# report less-useful error messages for unhashable
# requirements, complaining that there's no hash provided.
if req.link.is_vcs:
raise VcsHashUnsupported()
if req.link.is_existing_dir():
raise DirectoryUrlHashUnsupported()
# Unpinned packages are asking for trouble when a new version
# is uploaded. This isn't a security check, but it saves users
# a surprising hash mismatch in the future.
# file:/// URLs aren't pinnable, so don't complain about them
# not being pinned.
if not req.is_direct and not req.is_pinned:
raise HashUnpinned()
# If known-good hashes are missing for this requirement,
# shim it with a facade object that will provoke hash
# computation and then raise a HashMissing exception
# showing the user what the hash should be.
return req.hashes(trust_internet=False) or MissingHashes()
def _fetch_metadata_only(
self,
req: InstallRequirement,View on GitHub (pinned to d7d0d0a394)
Solutions
- Build an sdist or wheel from the directory and reference it by URL with a sha256 hash.
- Run pip wheel <dir> --no-deps -w ./wheels, then add the resulting wheel with its hash to the requirements file.
- Disable --require-hashes for the local-directory install if hashing is not required there.
- Package the local code into a proper distribution before hashing.
Example fix
# before (requirements.txt with --require-hashes) file:///opt/src/mylocalpkg # after: build a wheel and pin it ./wheels/mylocalpkg-1.0-py3-none-any.whl \ --hash=sha256:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789
Defensive patterns
Strategy: validation
Validate before calling
import os, urllib.parse
def is_directory_url(url: str) -> bool:
if not url.startswith("file://"):
return False
path = urllib.parse.urlparse(url).path
return os.path.isdir(path)
for req in requirements:
if require_hashes and is_directory_url(req.url):
raise SystemExit(f"directory URL cannot be hashed: {req.url}") Type guard
import os, urllib.parse
def is_directory_url(url: str) -> bool:
if not url.startswith("file://"):
return False
return os.path.isdir(urllib.parse.urlparse(url).path) Prevention
- Build a wheel from local directories before pinning by hash.
- Do not combine file:// directory requirements with --require-hashes.
- Package local code into a distribution for reproducible hashing.
When it happens
Trigger: pip install --require-hashes with a requirement like 'file:///path/to/pkgdir' or a local editable directory install while hash checking is mandatory. The directory as a whole cannot be checksummed.
Common situations: Hashed lockfiles that include a local source directory. CI that enforces --require-hashes but installs a vendored/monorepo package from a path.
Related errors
- Can't verify hashes for these requirements because we don't
- In --require-hashes mode, all requirements must have their v
- The editable requirement {req} cannot be installed when requ
- Unknown hash name: {hash_name}
- THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/4122f4fdeec96d27.json.
Report an issue: GitHub.