pypa/pip · error · SidecarMetadataInconsistent

Requested has inconsistent Requires-Dist between its PEP…

Error message

Requested {ireq} has inconsistent Requires-Dist between its PEP 658 .metadata file and the wheel's METADATA: sidecar has {f_val!r}, wheel has {m_val!r}

What it means

Raised by _check_sidecar_matches_wheel (prepare.py:315) as SidecarMetadataInconsistent for Requires-Dist. pip canonicalizes the dependency sets from both the sidecar and the wheel and compares them; if the sets differ it reports the symmetric difference (sidecar-only vs wheel-only) and aborts. This catches an index serving dependency metadata that does not match the wheel's actual dependencies.

Solutions

  1. Switch indexes or use PyPI directly to verify the package is consistent upstream.
  2. Clear the local cache and re-download.
  3. Pin to a known-good version whose metadata is consistent.
  4. Notify the index operator to fix/regenerate the sidecar.

Example fix

# before
pip install --index-url https://mirror/simple pkg
# after
pip install --no-cache-dir -i https://pypi.org/simple/ 'pkg==1.4.0'
Defensive patterns

Strategy: validation

Validate before calling

from email.parser import Parser
from pip._vendor.packaging.requirements import Requirement
import zipfile, io, requests

def _canon_set(msg):
    out = set()
    for raw in msg.get_all('Requires-Dist', []):
        r = Requirement(raw.strip())
        out.add(str(r))
    return frozenset(out)

def sidecar_requires_match(wheel_url: str, sidecar_url: str) -> bool:
    wb = requests.get(wheel_url).content
    zf = zipfile.ZipFile(io.BytesIO(wb))
    m_w = Parser().parsestr(zf.read(next(n for n in zf.namelist() if n.endswith('.dist-info/METADATA'))).decode())
    m_s = Parser().parsestr(requests.get(sidecar_url).text)
    return _canon_set(m_w) == _canon_set(m_s)

Type guard

from pip._vendor.packaging.requirements import Requirement

def dependency_sets_match(sidecar: list[str], wheel: list[str]) -> bool:
    def canon(items):
        return frozenset(str(Requirement(i.strip())) for i in items)
    return canon(sidecar) == canon(wheel)

Try / catch

from subprocess import run
# Fall back to a consistent index on mismatch.
run(["pip", "install", "--no-cache-dir", "-i", "https://pypi.org/simple/", pkg], check=True)

Prevention

When it happens

Trigger: The set of canonicalized Requires-Dist entries in the PEP 658 .metadata file differs from that in the wheel's METADATA. The message lists entries only in the sidecar vs only in the wheel.

Common situations: A republished wheel whose dependencies changed but the mirror's sidecar cache was not invalidated; an index that hand-generates metadata incorrectly; partial mirror synchronization.

Related errors


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

Appendix: source

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

    if sidecar_name != wheel_name:
        raise SidecarMetadataInconsistent(req, "Name", sidecar_name, wheel_name)

    if sidecar_dist.version != wheel_dist.version:
        raise SidecarMetadataInconsistent(
            req,
            "Version",
            str(sidecar_dist.version),
            str(wheel_dist.version),
        )

    # For multi-use fields, only report the symmetric difference to avoid
    # unnecessarily flagging matching values.
    sidecar_requires = _canonical_requires(
        req, sidecar_dist, "the PEP 658 .metadata file"
    )
    wheel_requires = _canonical_requires(req, wheel_dist, "the wheel's METADATA")
    if sidecar_requires != wheel_requires:
        raise SidecarMetadataInconsistent(
            req,
            "Requires-Dist",
            ", ".join(sorted(sidecar_requires - wheel_requires)),
            ", ".join(sorted(wheel_requires - sidecar_requires)),
        )

    if sidecar_dist.requires_python != wheel_dist.requires_python:
        raise SidecarMetadataInconsistent(
            req,
            "Requires-Python",
            str(sidecar_dist.requires_python),
            str(wheel_dist.requires_python),
        )

    sidecar_extras = frozenset(sidecar_dist.iter_provided_extras())
    wheel_extras = frozenset(wheel_dist.iter_provided_extras())
    if sidecar_extras != wheel_extras:
        raise SidecarMetadataInconsistent(

View on GitHub (pinned to f399c37189)