Skip to content

How to Debug uv Dependency Resolution Failures

When uv lock or uv add prints No solution found when resolving dependencies, the resolver found two requirements that no single version can satisfy. The error names both sides of the conflict, and that message is the fastest path to a fix.

Prerequisites

Read the error message

uv prints a derivation chain that traces the conflict from your project’s requirements to the incompatible ranges:

$ uv add 'urllib3>=2' 'botocore==1.29.0'
  × No solution found when resolving dependencies:
  ╰─▶ Because botocore==1.29.0 depends on urllib3>=1.25.4,<1.27 and your
      project depends on botocore==1.29.0, we can conclude that your project
      depends on urllib3>=1.25.4,<1.27.
      And because your project depends on urllib3>=2, we can conclude that
      your project's requirements are unsatisfiable.

Read it bottom-up. The last sentence states the contradiction: the project asks for urllib3>=2, but botocore==1.29.0 caps it at <1.27. No version of urllib3 satisfies both.

Trace the dependency tree

uv tree shows the full resolved graph. When a package appears in the error, run the inverted view to see everything that pulls it in. If resolution failed before any lockfile was written, remove the conflicting addition, lock the existing dependencies first, then inspect the tree.

$ uv tree --invert --package urllib3
urllib3 v2.7.0
├── botocore v1.29.0
│   └── uv-override-test v0.1.0
└── uv-override-test v0.1.0

The output names every path from urllib3 back to the project root. Two paths requesting incompatible ranges are the conflict.

Preview changes without committing

uv lock --dry-run resolves dependencies and reports what would change without writing the lockfileA file that records the exact version of every installed package, so everyone working on the project gets identical installs. :

$ uv lock --upgrade-package requests --dry-run
Resolved 6 packages in 1.64s
Update requests v2.32.3 -> v2.34.2

Combine --dry-run with --resolution lowest to check whether the declared lower bounds still resolve. Library authors use this to verify that a user on the oldest supported versions gets a working install:

$ uv lock --resolution lowest --dry-run
Resolved 6 packages in 2.60s
Update certifi v2026.7.22 -> v2023.5.7
Update charset-normalizer v3.4.9 -> v2.0.0
Update idna v3.18 -> v2.5
Update urllib3 v2.7.0 -> v1.26.0

Fix the conflict with an override

When a transitive dependencyA package your dependency depends on. When you install requests, its own dependencies (urllib3, certifi, etc.) are transitive dependencies. declares an incorrect upper bound, override it. Add override-dependencies under [tool.uv] in pyproject.toml to replace that package’s declared range:

pyproject.toml
[tool.uv]
override-dependencies = [
    "urllib3>=1.25.4",
]

This tells the resolver to ignore botocore’s urllib3<1.27 ceiling and accept any urllib3>=1.25.4. The override applies globally, so verify the result with uv tree to confirm the resolved version works.

Warning

Overrides bypass metadata that exists for a reason. Test the combination before shipping. If botocore genuinely breaks with urllib3>=2, the override hides the breakage instead of fixing it.

Narrow versions with a constraint

When the goal is to restrict rather than loosen, use constraint-dependencies. Constraints reduce the acceptable range without adding the package as a direct dependency:

pyproject.toml
[tool.uv]
constraint-dependencies = [
    "grpcio<1.65",
]

Use constraints to pin a transitive dependency below a known-broken release. Use overrides to widen past an incorrect ceiling. The two solve opposite problems.

Handle requires-python mismatches

uv resolves across all Python versions that requires-python allows. A project declaring requires-python = ">=3.9" forces the resolver to find versions compatible with 3.9 through the latest release, so if a dependency dropped 3.9 support, the resolver fails even on a 3.13 machine.

Either raise the floor in requires-python or pin the dependency to a version that still supports 3.9. For the full walkthrough, see how to fix Python version incompatibility errors in uv.

Learn More

Last updated on