Yes. When pip is given an extra index, it checks every location and picks the best version match, with no priority between them. If your internal mirror is one index and the public registry is another, a higher version number from the public side can win. Use a single index that fronts everything.
What the pip documentation says
The pip install reference states that pip looks in the main index, in the local filesystem, and in any extra repositories, and that there is no priority in the locations searched. All are checked and the best match for the requirement, in terms of version number, is selected.
That is the behaviour behind dependency confusion. If you publish an internal package called acme-billing at version 1.2.0 and someone publishes acme-billing at 9.0.0 on the public index, pip can legitimately prefer the public one when both indexes are searched.
Why this breaks the mirror idea
An intake design relies on one rule: every download goes through a place you control. A second index silently adds a second path. The mirror may still get traffic, but it no longer decides what gets installed.
The safer pattern
- Use one index URL. Point pip at a single internal endpoint with the standard index setting, not an extra one.
- Let the mirror merge the sources. Configure the repository manager to serve internal packages and a proxied copy of the public index behind that one URL, with rules for which names come from where.
- Reserve your internal names. Make the repository manager serve internal names only from your hosted repository, so a public package of the same name cannot be fetched.
- Remove the extra index setting from CI and developer config. Search templates, Dockerfiles and requirements files, because the option can be set in several places.
- Add hash checking for production installs. The pip secure installs guide describes hash-checking mode, where pip rejects any package whose hash does not match your requirements file.
Where to look for stray indexes
| Place | What to search for |
|---|---|
| requirements files | Lines that set an extra index |
| pip config files | Index settings at user, site and project level |
| Dockerfiles | Install commands with index flags |
| CI definitions | Environment variables that set index URLs |
| Tool configs | Poetry, pip-tools or similar tools that carry their own index lists |
Test it
Create a throwaway package name that exists only on your internal side, then request it from a clean environment. Next, add a higher version of the same name to a test public location if you can do that safely, and confirm the install still picks the internal one. If you cannot run that test, at least confirm in the repository manager that the name is blocked from public resolution.
Where Safeguard fits
Safeguard's dependency scanning and asset discovery can help you find which repositories and pipelines resolve packages in unexpected ways, and its policies can flag a dependency that did not come from an approved source. A free scan is a quick way to see your current inventory.
Quick check
Is the extra index option always wrong?
Not always, but it needs a clear reason and a name reservation strategy. For an intake design, one controlled index is simpler to reason about.
Does hash checking replace the need for a mirror?
No. Hashes prove a file matches what you recorded, but a mirror and policy decide what you record in the first place.
Sources
Last reviewed: 19 October 2026.