2025, Nov 10 07:00

Poetry, Artifactory, and Multi-Index Dependencies: Why 1.8.0 Broke Resolution and How 1.8.2 Fixes It

Behind a corporate proxy with Artifactory? See how a Poetry 1.8.0 multi-repository dependency bug breaks PyPI resolution and why upgrading to 1.8.2 fixes it.

When you’re stuck behind a corporate proxy and PyPI is routed through Artifactory, multi-repository setups can turn dependency resolution into a headache. A common pattern is to keep a primary proxy to public PyPI and a separate, fully isolated internal repository for in-house builds. The expectation is simple: fetch a specific internal wheel from the isolated repo, but resolve its transitive dependencies through the primary proxy. With Poetry 1.8.0, that scenario breaks in an Artifactory-backed environment.

Problem setup

Consider a configuration where the primary source points to a PyPI proxy, and a secondary source targets an internal, firewalled repository. The intention is to pull one internal package from the isolated index while relying on the primary source for everything else.

[[tool.poetry.source]]
name = "mirror_main"
url = "https://[COMPANY URL]/artifactory/api/pypi/pypi-release/simple"
priority = "primary"
[[tool.poetry.source]]
name = "mirror_isolated"
url = "https://[COMPANY URL]/artifactory/api/pypi/python-internal-unstable/simple"
priority = "supplemental"
[tool.poetry.dependencies]
python = "^3.10 <3.12"
numpy = "1.23.5"
pandas = "1.4.3"
corp_widget = {version = "X.Y.Z", source = "mirror_isolated"}

Running a lock or install with this setup under Poetry 1.8.0 can fail when the resolver tries to pull transitive dependencies from the isolated index that cannot see the wider PyPI. The error manifests during resolution, for example with a message along the lines of a package not being found:

poetry lock
# ...
# ValueError: Package('corp_widget', 'X.Y.Z') is not in list

With pip, the expected behavior is easy to achieve by combining an index URL for the internal package with an extra index URL for the public mirror. The following works because pip pulls the specified package from the isolated index, then falls back to the public proxy for transitive dependencies:

python -m pip install \
  --index-url https://[COMPANY URL]/artifactory/api/pypi/python-internal-unstable/simple/ \
  --extra-index-url https://[COMPANY URL]/artifactory/api/pypi/pypi-release/simple \
  corp_widget

Why Poetry failed here

This behavior stems from a bug in Poetry 1.8.0 related to Artifactory. Under that version, resolution could inappropriately stick to the secondary index for transitive dependencies when an internal package came from the isolated repository. The issue is documented here: https://github.com/python-poetry/poetry/issues/9056.

The fix

The problem was patched in Poetry 1.8.2. After upgrading, the same configuration behaves as intended: the internal package is fetched from the isolated repository, while transitive dependencies resolve via the primary proxy. The changelog entry is available here: https://python-poetry.org/history/#182---2024-03-02.

The working configuration remains unchanged. For clarity, here it is again:

[[tool.poetry.source]]
name = "mirror_main"
url = "https://[COMPANY URL]/artifactory/api/pypi/pypi-release/simple"
priority = "primary"
[[tool.poetry.source]]
name = "mirror_isolated"
url = "https://[COMPANY URL]/artifactory/api/pypi/python-internal-unstable/simple"
priority = "supplemental"
[tool.poetry.dependencies]
python = "^3.10 <3.12"
numpy = "1.23.5"
pandas = "1.4.3"
corp_widget = {version = "X.Y.Z", source = "mirror_isolated"}

Why it matters

Organizations frequently split repositories by trust level or network zone. In those environments, the ability to pin a single package to an isolated index while resolving its dependency tree elsewhere is essential to keep builds reproducible and secure. Divergent behavior between tools adds friction, so knowing that Poetry’s 1.8.2 release addresses this scenario helps align expectations with pip-style multi-index workflows.

Takeaways

If you are using Poetry with Artifactory and see failures when pulling a package from a secondary isolated source, verify your Poetry version. Upgrading to 1.8.2 resolves the bug so that a supplemental source can be used for the target package, while dependency resolution proceeds through the primary PyPI proxy. Keep your configuration clean and explicit, and validate in both connected and firewalled environments to ensure the resolver behaves the way your network architecture requires.

The article is based on a question from StackOverflow by MikeFenton and an answer by MikeFenton.