pypa/pip · error · MetadataInvalid

Requested has invalid metadata

Error message

Requested {self.ireq} has invalid metadata: {self.error}

What it means

_check_metadata_consistency (candidates.py:238-241) parses the distribution's Requires-Dist entries via iter_dependencies; if any dependency string raises InvalidRequirement, pip wraps it as MetadataInvalid. The package's own metadata violates PEP 508 requirement syntax.

Solutions

  1. Report the malformed metadata to the package maintainer.
  2. Pin to a version of the package known to have valid metadata.
  3. Fork/rebuild the package with corrected METADATA and install from your fixed source.
Defensive patterns

Strategy: validation

Validate before calling

# Validate a wheel's Requires-Dist entries parse as PEP 508 before install.
import zipfile, sys
from packaging.requirements import Requirement, InvalidRequirement
whl = sys.argv[1]
with zipfile.ZipFile(whl) as z:
    meta = [n for n in z.namelist() if n.endswith("METADATA")][0]
    for line in z.read(meta).decode().splitlines():
        if line.startswith("Requires-Dist:"):
            spec = line.split(":", 1)[1].strip()
            try:
                Requirement(spec)
            except InvalidRequirement as e:
                print(f"INVALID Requires-Dist in {whl}: {spec!r} ({e})")

Prevention

When it happens

Trigger: Installing a package whose METADATA contains a malformed Requires-Dist value (invalid PEP 508 specifier syntax), detected during candidate preparation.

Common situations: Upstream packaging bug; a hand-edited METADATA; a very old package using non-standard dependency notation.

Related errors


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

Appendix: source

Thrown at src/pip/_internal/resolution/resolvelib/candidates.py:241

                self._ireq,
                "name",
                self._name,
                dist.canonical_name,
            )
        if self._version is not None and self._version != dist.version:
            raise MetadataInconsistent(
                self._ireq,
                "version",
                str(self._version),
                str(dist.version),
            )
        # check dependencies are valid
        # TODO performance: this means we iterate the dependencies at least twice,
        # we may want to cache parsed Requires-Dist
        try:
            list(dist.iter_dependencies(list(dist.iter_provided_extras())))
        except InvalidRequirement as e:
            raise MetadataInvalid(self._ireq, str(e))

    def _prepare(self) -> BaseDistribution:
        try:
            dist = self._prepare_distribution()
        except HashError as e:
            # Provide HashError the underlying ireq that caused it. This
            # provides context for the resulting error message to show the
            # offending line to the user.
            e.req = self._ireq
            raise
        except InstallationSubprocessError as exc:
            if isinstance(self._ireq.comes_from, InstallRequirement):
                request_chain = self._ireq.comes_from.from_path()
            else:
                request_chain = self._ireq.comes_from

            if request_chain is None:
                request_chain = "directly requested"

View on GitHub (pinned to f399c37189)