aio-libs/aiohttp · error · ValueError

aiohttp only supports http(s) proxies

Error message

aiohttp only supports http(s) proxies (got: {proxy.scheme!r}).
See third-party libraries for other proxy schemes.

What it means

Raised by ClientRequest._update_proxy() when the proxy URL's scheme is not in HTTP_AND_EMPTY_SCHEMA_SET (i.e. not http, https, or empty). aiohttp's client only speaks HTTP(S) proxying (CONNECT for HTTPS, direct forwarding for HTTP); SOCKS or other schemes require a third-party library. The error includes the offending scheme to aid diagnosis.

Solutions

  1. Use an http:// or https:// proxy URL with aiohttp.
  2. For SOCKS proxies, install aiohttp-socks (or aiohttp_socks) and use its wrapper, which handles SOCKS4/5.
  3. Verify the scheme spelling — a missing/typo'd scheme triggers the same error.
  4. If you must route through SOCKS, run a local HTTP-to-SOCKS bridge and point aiohttp at it over http://.

Example fix

# before
await session.get(url, proxy='socks5://127.0.0.1:1080')  # ValueError

# after — use aiohttp-socks for SOCKS
from aiohttp_socks import ProxyConnector
connector = ProxyConnector.from_url('socks5://127.0.0.1:1080')
async with aiohttp.ClientSession(connector=connector) as session:
    await session.get(url)
# or, for an HTTP proxy:
await session.get(url, proxy='http://127.0.0.1:8080')
Defensive patterns

Strategy: validation

Validate before calling

from yarl import URL

def http_proxy(url):
    u = URL(url) if not isinstance(url, URL) else url
    if u.scheme not in ('http', 'https', ''):
        raise ValueError(f'aiohttp supports only http(s) proxies; got scheme {u.scheme!r}')
    return u

Type guard

from yarl import URL
def is_http_proxy(url) -> bool:
    try:
        u = URL(url) if not isinstance(url, URL) else url
    except Exception:
        return False
    return u.scheme in ('http', 'https', '')

Try / catch

try:
    await session.get(url, proxy=proxy_url)
except ValueError as e:
    if 'only supports http(s) proxies' in str(e):
        # switch to aiohttp_socks for SOCKS, or use an http proxy
        from aiohttp_socks import ProxyConnector
        connector = ProxyConnector.from_url(proxy_url)
        async with aiohttp.ClientSession(connector=connector) as s:
            await s.get(url)
    else:
        raise

Prevention

When it happens

Trigger: Passing proxy='socks5://127.0.0.1:1080' or proxy='ftp://...' to session.request / ClientSession(proxy=...). The scheme check fails and ValueError is raised at request setup.

Common situations: Using a SOCKS proxy URL with aiohttp directly (unsupported); copy-paste of a proxy URL intended for requests/urllib3 with socks support; mis-typed scheme ('httpd://'); expecting aiohttp to support arbitrary proxy schemes.

Related errors


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

Appendix: source

Thrown at aiohttp/client_reqrep.py:1388

            and self.headers[hdrs.EXPECT].lower() == "100-continue"
        ):
            expect = True

        if expect:
            self._continue = self.loop.create_future()

    def _update_proxy(
        self,
        proxy: URL | None,
        proxy_headers: CIMultiDict[str] | None,
    ) -> None:
        if proxy is None:
            self.proxy = None
            self.proxy_headers = None
            return

        if proxy.scheme not in HTTP_AND_EMPTY_SCHEMA_SET:
            raise ValueError(
                f"aiohttp only supports http(s) proxies (got: {proxy.scheme!r}).\n"
                "See third-party libraries for other proxy schemes."
            )

        # URL-embedded credentials on the proxy map to Proxy-Authorization.
        if proxy.raw_user or proxy.raw_password:
            auth_header = encode_basic_auth(proxy.user or "", proxy.password or "")
            if proxy_headers is None:
                proxy_headers = CIMultiDict()
            proxy_headers.setdefault(hdrs.PROXY_AUTHORIZATION, auth_header)
            proxy = proxy.with_user(None)
        self.proxy = proxy
        self.proxy_headers = proxy_headers

    def _create_response(
        self,
        task: asyncio.Task[None] | None,
        stream_writer: AbstractStreamWriter,

View on GitHub (pinned to d041d4d0fd)