pypa/pip · error · NoneMetadataError

None metadata found for distribution

Error message

None {metadata_name} metadata found for distribution: {dist}

What it means

In the legacy resolver, _check_metadata_requires_python reads dist.requires_python (resolver.py:78-80); if accessing it raises FileNotFoundError, pip wraps it as NoneMetadataError. This signals an inconsistency: the distribution claims metadata exists but the METADATA/PKG-INFO file is missing or unreadable.

Solutions

  1. Reinstall the offending package to restore its METADATA file.
  2. Fix filesystem permissions on the site-packages/dist-info directory.
  3. Remove the corrupted .dist-info directory and reinstall.
Defensive patterns

Strategy: validation

Validate before calling

# Verify METADATA files are readable for installed dists before resolving.
import importlib.metadata as md, pathlib
for dist in md.distributions():
    try:
        _ = dist.requires_python
    except FileNotFoundError:
        print(f"Corrupt dist (missing METADATA): {dist.metadata['Name']}")

Prevention

When it happens

Trigger: Resolving a package whose .dist-info directory exists but whose METADATA file is missing, deleted, or unreadable (permission error) at the moment pip reads requires_python.

Common situations: Corrupted/partial installs; filesystem permission issues; packages whose dist-info was partially deleted; broken symlinks.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/47a343b1a614ea51. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_internal/resolution/legacy/resolver.py:80

    """
    Check whether the given Python version is compatible with a distribution's
    "Requires-Python" value.

    :param version_info: A 3-tuple of ints representing the Python
        major-minor-micro version to check.
    :param ignore_requires_python: Whether to ignore the "Requires-Python"
        value if the given Python version isn't compatible.

    :raises UnsupportedPythonVersion: When the given Python version isn't
        compatible.
    """
    # This idiosyncratically converts the SpecifierSet to str and let
    # check_requires_python then parse it again into SpecifierSet. But this
    # is the legacy resolver so I'm just not going to bother refactoring.
    try:
        requires_python = str(dist.requires_python)
    except FileNotFoundError as e:
        raise NoneMetadataError(dist, str(e))
    try:
        is_compatible = check_requires_python(
            requires_python,
            version_info=version_info,
        )
    except specifiers.InvalidSpecifier as exc:
        logger.warning(
            "Package %r has an invalid Requires-Python: %s", dist.raw_name, exc
        )
        return

    if is_compatible:
        return

    version = ".".join(map(str, version_info))
    if ignore_requires_python:
        logger.debug(
            "Ignoring failed Requires-Python check for package %r: %s not in %r",

View on GitHub (pinned to f399c37189)