pypa/pip · error · MetadataInconsistent

Requested has inconsistent Name: expected , but metadata has

Error message

Requested {ireq} has inconsistent Name: expected {f_val!r}, but metadata has {m_val!r}

What it means

Raised by _fetch_metadata_using_link_data_attr (prepare.py:546) as MetadataInconsistent when the Name field in a fetched metadata-only distribution does not match the name of the InstallRequirement being resolved. This protects against an index returning metadata for a different project than requested (e.g. due to a name-collision or misrouted request).

Solutions

  1. Verify the exact canonical project name on PyPI and correct the requirement spelling.
  2. Switch to the official PyPI to rule out an index routing problem.
  3. Clear the local cache in case a stale metadata file was cached.
  4. If you publish the package, ensure the Name field in METADATA matches the distribution filename.

Example fix

# before
pip install Django-ORM   # wrong/colliding name
# after
pip install --no-cache-dir django
Defensive patterns

Strategy: validation

Validate before calling

from pip._vendor.packaging.utils import canonicalize_name

def requested_name_matches(req_name: str, metadata_name: str) -> bool:
    return canonicalize_name(req_name) == canonicalize_name(metadata_name)

# Before install: fetch the index metadata name and compare.
import requests, json

def pypi_name_for(project: str) -> str:
    data = requests.get(f"https://pypi.org/pypi/{project}/json", timeout=30).json()
    return data['info']['name']

Type guard

from pip._vendor.packaging.utils import canonicalize_name

def names_agree(requested: str, actual: str) -> bool:
    return canonicalize_name(requested) == canonicalize_name(actual)

Try / catch

from subprocess import run, CalledProcessError
try:
    run(["pip", "install", pkg], check=True)
except CalledProcessError:
    # Retry against the official index / corrected canonical name.
    run(["pip", "install", "--no-cache-dir", "-i", "https://pypi.org/simple/", canonical_name], check=True)

Prevention

When it happens

Trigger: While fetching PEP 658 / data-dist-info-metadata, the canonicalized Name from the downloaded METADATA differs from canonicalize_name(req.req.name). The metadata was advertised for a link but its Name field names another package.

Common situations: A typo or casing mismatch where the requested name doesn't match the project's actual canonical name; a mirror/index routing bug returning the wrong project's metadata; name-squatting or a rename where old/new names diverge.

Related errors


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

Appendix: source

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

            self._download,
            hashes=metadata_link.as_hashes(),
        )
        with open(metadata_file.path, "rb") as f:
            metadata_contents = f.read()
        # (3) Generate a dist just from those file contents.
        metadata_dist = get_metadata_distribution(
            metadata_contents,
            req.link.filename,
            req.req.name,
        )
        # (4) Ensure the Name: field from the METADATA file matches the name from the
        #     install requirement.
        #
        #     NB: raw_name will fall back to the name from the install requirement if
        #     the Name: field is not present, but it's noted in the raw_name docstring
        #     that that should NEVER happen anyway.
        if canonicalize_name(metadata_dist.raw_name) != canonicalize_name(req.req.name):
            raise MetadataInconsistent(
                req, "Name", req.req.name, metadata_dist.raw_name
            )
        return metadata_dist

    def _fetch_metadata_using_lazy_wheel(
        self,
        link: Link,
    ) -> BaseDistribution | None:
        """Fetch metadata using lazy wheel, if possible."""
        # --use-feature=fast-deps must be provided.
        if not self.use_lazy_wheel:
            return None
        if link.is_file or not link.is_wheel:
            logger.debug(
                "Lazy wheel is not used as %r does not point to a remote wheel",
                link,
            )
            return None

View on GitHub (pinned to f399c37189)