pypa/pip · error · DistributionNotFound

No matching distribution found for {req}

Error message

No matching distribution found for {req}

What it means

DistributionNotFound raised at the end of find_best_candidate when no installable candidate was found AND nothing satisfying is already installed. The classic 'No matching distribution found for X' message; it logs the available versions (or 'none') before raising.

Source

Thrown at src/pip/_internal/index/package_finder.py:1057

        if installed_version is None and best_candidate is None:
            # Check if only final releases are allowed for this package
            version_type = "version"
            if self.release_control is not None:
                allows_pre = self.release_control.allows_prereleases(
                    canonicalize_name(name)
                )
                if allows_pre is False:
                    version_type = "final version"

            logger.critical(
                "Could not find a %s that satisfies the requirement %s "
                "(from versions: %s)",
                version_type,
                req,
                _format_versions(best_candidate_result.all_candidates),
            )

            raise DistributionNotFound(f"No matching distribution found for {req}")

        def _should_install_candidate(
            candidate: InstallationCandidate | None,
        ) -> TypeGuard[InstallationCandidate]:
            if installed_version is None:
                return True
            if best_candidate is None:
                return False
            return best_candidate.version > installed_version

        if not upgrade and installed_version is not None:
            if _should_install_candidate(best_candidate):
                logger.debug(
                    "Existing installed version (%s) satisfies requirement "
                    "(most up-to-date version is %s)",
                    installed_version,
                    best_candidate.version,
                )

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Verify the package name spelling and that it exists on the configured index (pip index versions <name> or check pypi.org).
  2. Loosen the version specifier (drop ==, widen >=) so an existing release can match.
  3. Check 'from versions:' in the log - if 'none', the index returned nothing (network/index URL issue or fully-incompatible requires-python).
  4. Allow sdists by removing --only-binary, or allow prereleases with --pre if only pre-releases exist.

Example fix

# before
pip install 'somepkg==1.2.4'   # version does not exist

# after
pip index versions somepkg        # see what exists
pip install 'somepkg>=1.2,<2'      # pick an existing release
Defensive patterns

Strategy: try-catch

Validate before calling

import subprocess, json, urllib.request
# 1) check package exists
try:
    json.load(urllib.request.urlopen(f'https://pypi.org/pypi/{name}/json'))
except urllib.error.HTTPError:
    print('package not found on index')
# 2) check specifier has any match
from packaging.requirements import Requirement
req = Requirement(spec)
releases = [Version(v) for v in data['releases']]
if not any(req.specifier.contains(v, prereleases=True) for v in releases):
    print('no version satisfies', spec)

Type guard

def requirement_satisfiable(name: str, spec: str) -> bool:
    import urllib.request, json
    from packaging.requirements import Requirement
    from packaging.version import Version
    d = json.load(urllib.request.urlopen(f'https://pypi.org/pypi/{name}/json'))
    req = Requirement(f'{name}{spec}')
    return any(req.specifier.contains(Version(v), prereleases=True)
               for v in d['releases'])

Try / catch

from pip._internal.exceptions import DistributionNotFound
try:
    pip.main(['install', req])
except DistributionNotFound as e:
    # log; suggest checking name/version/Python compat
    ...

Prevention

When it happens

Trigger: Reached when installed_version is None and best_candidate is None after filtering all candidates by platform tags, requires-python, format control, prerelease policy, and hashes. Typo in package name, no compatible wheel/sdist on the index, or all versions excluded by version specifiers.

Common situations: Misspelled package name; requiring a version specifier that no release satisfies (e.g. '==1.2.4' that doesn't exist); Python version too new/old for every release (requires-python excludes all); index unreachable or empty; --only-binary with no wheel available; offline install with no local index.

Related errors


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