aio-libs/aiohttp · error · ClientHttpProxyError

ClientHttpProxyError: {message}

Error message

ClientHttpProxyError: {message}

What it means

Raised inside _create_proxy_connection when the proxy's response to the CONNECT request has a status other than 200. aiohttp had successfully established a transport to the proxy and issued CONNECT host:port, but the proxy refused to tunnel (401/403/407/502/etc.). The proxy's reason phrase (or the HTTPStatus phrase if reason is missing) is carried as the message, so the failure cause from the proxy is visible.

Source

Thrown at aiohttp/connector.py:1641

                # once the response is received and processed allowing
                # START_TLS to work on the connection below.
                protocol.set_response_params(
                    read_until_eof=True,
                    timeout_ceil_threshold=self._timeout_ceil_threshold,
                )
                resp = await proxy_resp.start(conn)
            except BaseException:
                proxy_resp.close()
                conn.close()
                raise
            else:
                conn._protocol = None
                try:
                    if resp.status != 200:
                        message = resp.reason
                        if message is None:
                            message = HTTPStatus(resp.status).phrase
                        raise ClientHttpProxyError(
                            proxy_resp.request_info,
                            resp.history,
                            status=resp.status,
                            message=message,
                            headers=resp.headers,
                        )
                except BaseException:
                    # It shouldn't be closed in `finally` because it's fed to
                    # `loop.start_tls()` and the docs say not to touch it after
                    # passing there.
                    transport.close()
                    raise

                return await self._start_tls_connection(
                    # Access the old transport for the last time before it's
                    # closed and forgotten forever:
                    transport,
                    req=req,

View on GitHub (pinned to d041d4d0fd)

Solutions

  1. Supply proxy credentials via the proxy URL (http://user:pass@proxy:port) or proxy_headers Authorization/Proxy-Authorization.
  2. Verify the proxy allows CONNECT to the target host and port (proxy ACL).
  3. Check HTTP_PROXY/HTTPS_PROXY/NO_PROXY env vars for stale or mistyped values.
  4. Reproduce with curl -x http://proxy:port https://target to confirm the proxy, not aiohttp, is rejecting.

Example fix

# before
await session.get('https://target/', proxy='http://corp-proxy:8080')
# after - add proxy auth
from urllib.parse import quote
proxy = 'http://{}:{}@corp-proxy:8080'.format(quote(user), quote(password))
await session.get('https://target/', proxy=proxy)
Defensive patterns

Strategy: try-catch

Validate before calling

from urllib.parse import urlparse, quote

def proxy_with_auth(proxy_url, user, password):
    p = urlparse(proxy_url)
    userinfo = f'{quote(user, safe="")}:{quote(password, safe="")}@'
    return f'{p.scheme}://{userinfo}{p.hostname}:{p.port}'

proxy = proxy_with_auth(base_proxy, user, password)

Type guard

null

Try / catch

try:
    resp = await session.get(url, proxy=proxy)
except aiohttp.ClientHttpProxyError as exc:
    if exc.status in (401, 407):
        proxy = refresh_proxy_credentials()
        resp = await session.get(url, proxy=proxy)
    else:
        raise

Prevention

When it happens

Trigger: Proxy requires authentication that was not supplied (407 Proxy Authentication Required); proxy denied by ACL (403); proxy could not reach the upstream (502/504); wrong proxy URL; proxy requires credentials in a different scheme (Basic vs Digest); expired proxy credentials.

Common situations: Corporate proxy credentials rotated; environment HTTP_PROXY/HTTPS_PROXY pointing at the wrong proxy; proxy auth header not set because aiohttp's proxy auth was not configured; proxy blocking the target host by policy.

Related errors


AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11). Data as JSON: /api/errors/97fc26728e73c2a3. Report an issue: GitHub.