poetry icon indicating copy to clipboard operation
poetry copied to clipboard

Auth failure when installing from multiple private repos

Open BruceWangTRT opened this issue 5 years ago • 13 comments

  • [x] I am on the latest Poetry version.
  • [x] I have searched the issues of this repo and believe that this is not a duplicate.
  • [x] If an exception occurs when executing a command, I executed it again in debug mode (-vvv option).
  • OS version and name: Ubuntu 18.04
  • Poetry version: 1.1.4

pyproject.toml:

...
[[tool.poetry.source]]
name = "repo1"
url = "url1"

[[tool.poetry.source]]
name = "repo2"
url = "url2"

[tool.poetry.dependencies]
package1 = "1.0.0" # from repo1
package2 = "2.0.0" # from repo2
...

And the credentials are set like this:

poetry config http-basic.repo1 USERNAME1 PASSWORD1
poetry config http-basic.repo2 USERNAME2 PASSWORD2 

Everything is locked perfectly in poetry.lock with both repos marked as type = legacy.

Issue

It is time for poetry install and I expect both packages to be installed. It turns out that only package1 will be installed and package2 will give this error:

RepositoryError

  401 Client Error: Unauthorized for url: url2

  at /usr/local/lib/python3.7/site-packages/poetry/repositories/legacy_repository.py:393 in _get
      389│             if response.status_code == 404:
      390│                 return
      391│             response.raise_for_status()
      392│         except requests.HTTPError as e:
    → 393│             raise RepositoryError(e)
      394│
      395│         if response.status_code in (401, 403):
      396│             self._log(
      397│                 "Authorization error accessing {url}".format(url=url), level="warn"

If I explicitly set repository through poetry config repositories.repo2 url2, it works the other way around. Now package2 is installed and package1 will give the same error:

RepositoryError

  401 Client Error: Unauthorized for url: url1

  at /usr/local/lib/python3.7/site-packages/poetry/repositories/legacy_repository.py:393 in _get
      389│             if response.status_code == 404:
      390│                 return
      391│             response.raise_for_status()
      392│         except requests.HTTPError as e:
    → 393│             raise RepositoryError(e)
      394│
      395│         if response.status_code in (401, 403):
      396│             self._log(
      397│                 "Authorization error accessing {url}".format(url=url), level="warn"

My first thought is that if I also do poetry config repositories.repo1 url1, it will fix it. No, it did not. Same error for package1:

RepositoryError

  401 Client Error: Unauthorized for url: url1

  at /usr/local/lib/python3.7/site-packages/poetry/repositories/legacy_repository.py:393 in _get
      389│             if response.status_code == 404:
      390│                 return
      391│             response.raise_for_status()
      392│         except requests.HTTPError as e:
    → 393│             raise RepositoryError(e)
      394│
      395│         if response.status_code in (401, 403):
      396│             self._log(
      397│                 "Authorization error accessing {url}".format(url=url), level="warn"

Maybe disable the parallel installer will fix it now that I have both repositories in poetry configuration. I did poetry config installer.parallel false. And my config looks like this (from poetry config --list, the same checked with --local):

cache-dir = "some-fir"
experimental.new-installer = true
installer.parallel = true
repositories.repo1.url = "url1"
repositories.repo2.url = "url2"
virtualenvs.create = true
virtualenvs.in-project = true

No, it gave me the same error for package1.

I also tried to clear pip and poetry cache by removing .cache/pip and .cache/poetry. It did not made a difference.

Finally, I reverted poetry configuration by unsetting the repositories and re-enabling parallel installer. And create a set of universal credentials for both repositories and set it like this:

poetry config http-basic.repo1 THE_USERNAME THE_PASSWORD
poetry config http-basic.repo2 THE_USERNAME THE_PASSWORD 

And it worked. Both packages were installed without issue!

BruceWangTRT avatar Oct 26 '20 18:10 BruceWangTRT

Might be related to #3216

BruceWangTRT avatar Oct 26 '20 18:10 BruceWangTRT

Please see https://github.com/python-poetry/poetry/issues/3303

dvf avatar Oct 28 '20 17:10 dvf

I hit this as well today and I can't get this working with any of the workarounds posted in the linked issues. In my case I am using multiple private Gitlab registries and they return 401, not 403. Locking also works as described the author of this issue. This makes this a real blocker for us.

languitar avatar Apr 14 '21 09:04 languitar

Alright, in my case I had a .netrc file on my system from an old experiment. This overwrites the credentials from the config. That order looks a bit strange, though. I would expect that the specific poetry configuration has a higher priority than a generic .netrc file.

languitar avatar Apr 14 '21 11:04 languitar

Hello There May be it seems obvious for others but I am pretty sure it is not for someones. You have to be careful about the authentication mode expected by your private repo. either USER-PASSWORD or USER-ACCESS_TOKEN. I have encountered the same issue mentionned here, except that I work on gitlab where it expects a combination of username-access_token and not username-password; which means instead of doing poetry config http-basic.reponame ${USERNAME} ${PASSWORD} you should do poetry config http-basic.reponame ${USERNAME} ${ACCESS_TOKEN}; and it worked perfectly (even in docker container). Again, it may be different on artifactory or pyserver or other private repos, but you have to check with mode is expected by your private server.

thynquest avatar Feb 16 '22 10:02 thynquest

@languitar issue happened for me as well. This should definitely be in the docs and/or re-prioritized. Very hard to notice it was happening too.

ericmillsio avatar Jul 01 '22 16:07 ericmillsio

Hello There May be it seems obvious for others but I am pretty sure it is not for someones. You have to be careful about the authentication mode expected by your private repo. either USER-PASSWORD or USER-ACCESS_TOKEN. I have encountered the same issue mentionned here, except that I work on gitlab where it expects a combination of username-access_token and not username-password; which means instead of doing poetry config http-basic.reponame ${USERNAME} ${PASSWORD} you should do poetry config http-basic.reponame ${USERNAME} ${ACCESS_TOKEN}; and it worked perfectly (even in docker container). Again, it may be different on artifactory or pyserver or other private repos, but you have to check with mode is expected by your private server.

Good to know it worked. I am also using gitlab. When i hardcode the http-basic.reponane {User} {Token} in Docker file its works. But when i try to pass {User} and {Token} from docker-compose args then it doesnt work. Any clue on how to make it work

priyankabishnoi avatar May 02 '23 15:05 priyankabishnoi

I also faced this issue today (poetry version is 1.5.1). I have 2 repositories with their corresponding credentials set up (via poetry config).

When I try to install a package from repository2, poetry tries to authenticate with credentials1 (those from repository1), hence the error. I had to debug the actual HTTP requests to notice this. It does seem multiple sources do not quite work.

jarandaf avatar Aug 02 '23 11:08 jarandaf

Same problem here on Poetry 1.6.1

cprevosteau avatar Oct 05 '23 08:10 cprevosteau

Alright, in my case I had a .netrc file on my system from an old experiment. This overwrites the credentials from the config. That order looks a bit strange, though. I would expect that the specific poetry configuration has a higher priority than a generic .netrc file.

Thank you, my friend! Resolved my problem)))

Nataliyi avatar Oct 12 '23 14:10 Nataliyi

Same problem here on Poetry 1.6.1

2.1.4 still behaving like described above

just for record, setting username & pwd in the "source" url in pyproject.toml does not change anything

supplying username & pwd via POETRY_HTTP_BASIC_* env vars does not work as well

so in any case, poetry, or implicit pip usage within poetry, looks into .netrc despite having a pip.conf ... :)

adrpp avatar Aug 05 '25 12:08 adrpp

Same issue as above, and took me far too long to find the .netrc file with the old credentials in it. It even overrode me putting credentials directly into the URL.

The values from .netrc should be deprioritized, or at the very least, very verbose logging should log where the credentials are being sourced from.

Brideau avatar Sep 04 '25 16:09 Brideau

bro i spent 5 hours on that, same as @Brideau

yiorgoskost avatar Sep 09 '25 09:09 yiorgoskost