psf/requests · error · InvalidProxyURL

Please check proxy URL. It is malformed and could be missing

Error message

Please check proxy URL. It is malformed and could be missing the host.

What it means

InvalidProxyURL is raised in HTTPAdapter.get_connection_with_tls_context when the proxy URL selected for a request parses to no host. requests first prepends 'http://' if the scheme is missing, then runs urllib3's parse_url; if the result still has an empty host (e.g. 'http://' alone, or a value that parses as scheme-only/path-only), it cannot build a proxy connection pool and rejects the URL up front.

Source

Thrown at src/requests/adapters.py:496

        :rtype:
            urllib3.HTTPConnectionPool
        """
        assert _is_prepared(request)

        proxy = select_proxy(request.url, proxies)
        try:
            host_params, pool_kwargs = self.build_connection_pool_key_attributes(
                request,
                verify,
                cert,
            )
        except ValueError as e:
            raise InvalidURL(e, request=request)
        if proxy:
            proxy = prepend_scheme_if_needed(proxy, "http")
            proxy_url = parse_url(proxy)
            if not proxy_url.host:
                raise InvalidProxyURL(
                    "Please check proxy URL. It is malformed "
                    "and could be missing the host."
                )
            proxy_manager = self.proxy_manager_for(proxy)
            conn = proxy_manager.connection_from_host(
                **host_params, pool_kwargs=pool_kwargs
            )
        else:
            # Only scheme should be lower case
            conn = self.poolmanager.connection_from_host(
                **host_params, pool_kwargs=pool_kwargs
            )

        return conn

    def get_connection(
        self, url: str, proxies: dict[str, str] | None = None
    ) -> HTTPConnectionPool:

View on GitHub ↗ (pinned to 414f0513c3)

Solutions

  1. Print/inspect the effective proxy (session.proxies plus HTTP_PROXY/HTTPS_PROXY/ALL_PROXY env vars) and fix or unset the malformed one
  2. Ensure the proxy URL has a host: 'http://proxyhost:3128', not 'http://' or ':3128'
  3. Percent-encode special characters in proxy credentials (urllib.parse.quote for user/password)
  4. If no proxy is wanted, pass proxies={} or use Session(trust_env=False) so stray env vars are ignored

Example fix

# before
os.environ['HTTPS_PROXY'] = 'http://'  # placeholder left in CI
requests.get(url)  # InvalidProxyURL

# after
from urllib.parse import quote
proxy = f'http://{quote(user)}:{quote(pw)}@proxy.corp.example:3128'
requests.get(url, proxies={'https': proxy, 'http': proxy})
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse
parsed = urlparse(proxy_url)
if not parsed.scheme or not parsed.hostname:
    raise ValueError(f"Proxy URL missing scheme or host: {proxy_url!r}")

Try / catch

from requests.exceptions import InvalidProxyURL
try:
    resp = session.get(url, proxies=proxies)
except InvalidProxyURL as e:
    raise RuntimeError(f"Malformed proxy URL in config: {proxies}") from e

Prevention

When it happens

Trigger: proxies={'https': 'http://'} or proxies={'https': ':8080'} or an empty-host value like 'http://:3128'; HTTP_PROXY/HTTPS_PROXY env vars set to malformed values (a bare scheme, a stray colon, unencoded special characters in credentials that break parsing). Raised at src/requests/adapters.py:495-499 during every send when a proxy matches the request URL.

Common situations: Env vars exported with empty or placeholder values in CI/shell profiles (export HTTPS_PROXY=http://); templated config where the proxy host variable expanded to empty; passwords containing @ or : that aren't percent-encoded, corrupting the parsed host; copy-paste of 'host:port' handled fine, but 'http://user:p@ss@host' failing.

Related errors


AI-assisted analysis of psf/requests@414f0513c3 (2026-07-31). Data as JSON: /data/errors/825b20b7267f0bd1.json. Report an issue: GitHub ↗.