devpi pip "401 Unauthorized" via extra-index-url in CI
pip reached the devpi index but received 401. The --extra-index-url carried no credentials, or the devpi user/token embedded in the URL is missing or wrong. The index is reachable; auth is not.
What this error means
pip install fails with "401 Client Error: Unauthorized" for the devpi index URL while public PyPI packages install fine.
ERROR: HTTP error 401 Client Error: Unauthorized for url:
https://devpi.internal.example.com/acme/prod/+simple/internal-lib/
ERROR: Could not find a version that satisfies the requirement internal-libCommon causes
No credentials in the extra index URL
The private devpi index requires auth for that index path, but the URL was configured without a user:token, so pip is anonymous.
A stale or wrong devpi token
The devpi user token embedded in the URL or netrc was rotated, so the request is unauthorized.
How to fix it
Embed the devpi credentials via a secret
- Create or fetch a devpi user token.
- Set
PIP_EXTRA_INDEX_URLwithuser:tokenfrom a CI secret. - Re-run so pip authenticates to the private index.
env:
PIP_EXTRA_INDEX_URL: https://acme-ci:${{ secrets.DEVPI_TOKEN }}@devpi.internal.example.com/acme/prod/+simple/Use netrc instead of URL credentials
Store the credentials in a .netrc so they are not in command lines or logs.
machine devpi.internal.example.com
login acme-ci
password ${DEVPI_TOKEN}How to prevent it
- Keep devpi tokens in CI secrets, never in committed config.
- Prefer
.netrcso credentials stay out of command output. - Rotate devpi tokens and update the secret in one place.