python-poetry/poetry · error · RepositoryError

{e}

Error message

{e}

What it means

RepositoryError wraps a requests.exceptions.HTTPError raised while fetching a repository page in HTTPRepository._get_response (http_repository.py:553-554). It is raised after the request exits the retry loop with a non-retryable (or final-attempt) HTTP error from raise_for_status(). This is the generic transport/status failure for repository HTTP calls.

Source

Thrown at src/poetry/repositories/http_repository.py:554

    def _get_response(
        self, endpoint: str, *, headers: dict[str, str] | None = None
    ) -> requests.Response | None:
        url = self._url + endpoint
        try:
            response: requests.Response = self.session.get(
                url, raise_for_status=False, timeout=REQUESTS_TIMEOUT, headers=headers
            )
            if response.status_code in (401, 403):
                self._log(
                    f"Authorization error accessing {url}",
                    level="warning",
                )
                return None
            if response.status_code == 404:
                return None
            response.raise_for_status()
        except requests.exceptions.HTTPError as e:
            raise RepositoryError(e)

        if response.url != url:
            self._log(
                f"Response URL {response.url} differs from request URL {url}",
                level="debug",
            )
        return response

    def _get_prefer_json_header(self) -> dict[str, str]:
        # Prefer json, but accept anything for backwards compatibility.
        # Although the more specific value should be preferred to the less specific one
        # according to https://developer.mozilla.org/en-US/docs/Glossary/Quality_values,
        # we add a quality value because some servers still prefer html without one.
        return {"Accept": "application/vnd.pypi.simple.v1+json, */*;q=0.1"}

    def _is_json_response(self, response: requests.Response) -> bool:
        return (
            response.headers.get("Content-Type", "").split(";")[0].strip()

View on GitHub (pinned to 92b74dcfe3)

Solutions

  1. Check that the repository URL in [[tool.poetry.source]] is correct and reachable (curl -I the simple index).
  2. Retry later if the server is returning transient 5xx errors.
  3. If behind a proxy, verify HTTP_PROXY/HTTPS_PROXY and corporate proxy behavior.
  4. Inspect the wrapped exception (str(e) is the original HTTPError) for the exact status code.
Defensive patterns

Strategy: retry

Validate before calling

# Smoke-check reachability before heavy resolution
import requests
try:
    requests.head(repository_url, timeout=10).raise_for_status()
except requests.RequestException as e:
    raise RuntimeError(f"repository unreachable: {e}") from e

Try / catch

from poetry.repositories.exceptions import RepositoryError
attempts = 0
while True:
    try:
        page = repository._get_page(name)
        break
    except RepositoryError as e:
        attempts += 1
        if attempts >= 3:
            raise
        time.sleep(2 ** attempts)

Prevention

When it happens

Trigger: Any repository page fetch returning a 5xx (after STATUS_FORCELIST retries are exhausted) or another status that requests treats as HTTPError; also raised when raise_for_status() trips inside the response handling.

Common situations: Index/mirror server down or returning 500/502/503; a corporate proxy returning an unexpected status; a malformed repository URL returning an HTML error page with a success-ish code path.

Related errors


AI-assisted analysis of python-poetry/poetry@92b74dcfe3 (2026-08-04). Data as JSON: /data/errors/5338d7b787a44104.json. Report an issue: GitHub.