pypa/pip · error · MetadataInvalid

Requested {ireq} has invalid metadata: Requires-Dist in {sou

Error message

Requested {ireq} has invalid metadata: Requires-Dist in {source}: {e}

What it means

Raised as MetadataInvalid when canonicalizing a Requires-Dist entry from a distribution's metadata fails to parse as a valid PEP 508 requirement. At prepare.py:266-273, _canonical_requires iterates raw dependency strings and calls _canonicalize_requirement, which uses get_requirement(raw.strip()); an InvalidRequirement propagates and is wrapped with the metadata source name.

Source

Thrown at src/pip/_internal/operations/prepare.py:273


def _canonical_requires(
    req: InstallRequirement, dist: BaseDistribution, source: str
) -> frozenset[str]:
    """Return the canonicalized ``Requires-Dist`` entries of ``dist``.

    ``source`` describes which metadata file ``dist`` was parsed from, for
    use in error messages.
    """
    canonical: set[str] = set()
    for raw in dist.iter_raw_dependencies():
        try:
            # strip() because a folded metadata header may be returned
            # with a leading newline; iter_dependencies() strips for the
            # same reason.
            canonical.add(_canonicalize_requirement(raw.strip()))
        except InvalidRequirement as e:
            raise MetadataInvalid(req, f"Requires-Dist in {source}: {e}")
    return frozenset(canonical)


def _check_sidecar_matches_wheel(
    req: InstallRequirement,
    sidecar_dist: BaseDistribution,
    wheel_dist: BaseDistribution,
) -> None:
    """Check that a .metadata-based distribution matches the wheel's METADATA.

    Compare ``Name``, ``Version``, ``Requires-Dist``, ``Requires-Python``
    and ``Provides-Extra`` between the two and abort the install on any
    mismatch as PEP 658 requires the metadata files "MUST be identical".

    While the PEP doesn't mandate that consumers enforce the identical
    requirement, it's good nonetheless to check to prevent confusing
    behaviour when an index misbehaves.

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Open the offending *.dist-info/METADATA and review the Requires-Dist lines for syntax errors.
  2. Fix the requirement string to conform to PEP 508 (e.g. 'dep>=1.0; python_version<"3.12"').
  3. Rebuild the wheel with a current build backend and reinstall.
  4. Pin to a version of the package whose metadata is valid.

Example fix

# before (METADATA)
Requires-Dist: numpy >=1.20, <2  # commas inside specifier are invalid in one entry

# after
Requires-Dist: numpy>=1.20,<2
Defensive patterns

Strategy: validation

Validate before calling

from pip._vendor.packaging.requirements import InvalidRequirement, Requirement

def validate_requires_dist(metadata_text):
    for line in metadata_text.splitlines():
        if line.startswith("Requires-Dist:"):
            raw = line.split(":", 1)[1].strip()
            try:
                Requirement(raw)
            except InvalidRequirement as e:
                raise ValueError(f"invalid Requires-Dist {raw!r}: {e}")

Type guard

from pip._vendor.packaging.requirements import Requirement, InvalidRequirement
def is_valid_requirement_str(raw: str) -> bool:
    try:
        Requirement(raw)
        return True
    except InvalidRequirement:
        return False

Prevention

When it happens

Trigger: A distribution (wheel METADATA or a PEP 658 .metadata sidecar) contains a Requires-Dist line that packaging's Requirement parser rejects — e.g. malformed specifier, illegal characters, or a non-PEP-508 syntax. The 'source' in the message indicates whether it was the sidecar or the wheel METADATA.

Common situations: A package built with an old/non-compliant tool, hand-edited METADATA, a corrupted download, or a metadata field containing unsupported syntax (e.g. environment markers in an unexpected position).

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/4b26797bd9e49aad.json. Report an issue: GitHub.