pypa/pip · error · VersionConflict

{self.dist} is installed but {self.req} is required

Error message

{self.dist} is installed but {self.req} is required

What it means

Raised as VersionConflict by WorkingSet.find() when a distribution for the requested project IS installed and active, but its version does not satisfy the given Requirement. The message names the installed distribution and the requirement that failed. This is a dependency-version mismatch detected against the active working set.

Source

Thrown at src/pip/_vendor/pkg_resources/__init__.py:724

        If there is an active distribution for the requested project, this
        returns it as long as it meets the version requirement specified by
        `req`.  But, if there is an active distribution for the project and it
        does *not* meet the `req` requirement, ``VersionConflict`` is raised.
        If there is no active distribution for the requested project, ``None``
        is returned.
        """
        dist = self.by_key.get(req.key)

        if dist is None:
            canonical_key = self.normalized_to_canonical_keys.get(req.key)

            if canonical_key is not None:
                req.key = canonical_key
                dist = self.by_key.get(canonical_key)

        if dist is not None and dist not in req:
            # XXX add more info
            raise VersionConflict(dist, req)
        return dist

    def iter_entry_points(self, group: str, name: str | None = None):
        """Yield entry point objects from `group` matching `name`

        If `name` is None, yields all entry points in `group` from all
        distributions in the working set, otherwise only ones matching
        both `group` and `name` are yielded (in distribution order).
        """
        return (
            entry
            for dist in self
            for entry in dist.get_entry_map(group).values()
            if name is None or name == entry.name
        )

    def run_script(self, requires: str, script_name: str):
        """Locate distribution for `requires` and run `script_name` script"""

View on GitHub (pinned to f399c37189)

Solutions

  1. Upgrade the conflicting package to a version satisfying the requirement: pip install 'package>=<required>'.
  2. Loosen the requirement specifier to include the installed version, if the older version is actually acceptable.
  3. Recreate the virtualenv from a clean requirements lock file so all versions are consistent.

Example fix

// before
# requests 2.20 installed, requirement is requests>=2.25
working_set.find(Requirement.parse('requests>=2.25'))
// after
# install a compatible version first
pip install 'requests>=2.25'
working_set.find(Requirement.parse('requests>=2.25'))
Defensive patterns

Strategy: try-catch

Validate before calling

# Pre-check installed version before calling find/require
import pkg_resources
installed = pkg_resources.get_distribution('requests').version
if not Requirement.parse('requests>=2.25').specifier.contains(installed):
    print(f'Need >=2.25, have {installed}')

Try / catch

try:
    working_set.find(req)
except VersionConflict as e:
    print(e.report())  # '{dist} is installed but {req} is required'

Prevention

When it happens

Trigger: Calling working_set.find(Requirement.parse('requests>=2.25')) when requests 2.20.0 is the active distribution; require('package>=X') where the installed version is older.

Common situations: A virtualenv with a stale or mismatched package version after a partial upgrade; pinning a higher minimum in requirements but not reinstalling; dependency conflicts surfaced when a plugin or entry point loads.

Related errors


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