psf/requests · error · InvalidSchema

Missing dependencies for SOCKS support.

Error message

Missing dependencies for SOCKS support.

What it means

This error is raised by a stub SOCKSProxyManager that replaces the real one when the optional PySocks dependency is absent. The requests library imports SOCKSProxyManager from urllib3.contrib.socks, which itself requires the 'PySocks' package. If that import fails at module load time, requests installs a fallback function that raises InvalidSchema with this message whenever a SOCKS proxy URL (socks5://, socks4://, etc.) is actually used.

Solutions

  1. Install the SOCKS extra: pip install 'requests[socks]' (or pip install PySocks requests).
  2. Verify PySocks is importable in the same interpreter the app uses: python -c "import socks; print(socks.__version__)".
  3. If SOCKS is unintended, switch the proxy config to an http:// or https:// proxy so the stub is never invoked.
  4. For lock-file based setups (pip-tools, Poetry, PDM), regenerate the lock so PySocks is pinned and present.
  5. In Docker/CI images, add PySocks to the requirements stage and confirm it is copied into the final image.

Example fix

# before
pip install requests
# proxies={"http": "socks5://127.0.0.1:1080"}  -> InvalidSchema

# after
pip install 'requests[socks]'
Defensive patterns

Strategy: validation

Validate before calling

# Before configuring any SOCKS proxy, confirm PySocks is importable.
import importlib.util

_wants_socks = any(
    str(p).lower().startswith("socks")
    for p in (proxies or {}).values()
    if p
)
if _wants_socks and importlib.util.find_spec("socks") is None:
    raise RuntimeError(
        "SOCKS proxy requested but PySocks is not installed. "
        "Install with: pip install 'requests[socks]'"
    )

Type guard

from urllib3.util import parse_url

def is_usable_proxy(proxy: str | None) -> bool:
    """True if proxy is None/empty (no proxy) or a non-SOCKS scheme,
    OR a SOCKS scheme with PySocks available."""
    if not proxy:
        return True
    scheme = (parse_url(proxy).scheme or "").lower()
    if scheme.startswith("socks"):
        import importlib.util
        return importlib.util.find_spec("socks") is not None
    return True

Try / catch

import requests.exceptions as exc

try:
    resp = session.get(url, proxies=proxies)
except exc.InvalidSchema as e:
    if "SOCKS" in str(e):
        raise RuntimeError(
            "SOCKS proxy requested but PySocks missing; "
            "run: pip install 'requests[socks]'"
        ) from e
    raise

Prevention

When it happens

Trigger: Triggered when the caller passes a SOCKS proxy (e.g. socks5://127.0.0.1:1080) via the proxies argument, the requests session proxies, or HTTP(S)_PROXY/ALL_PROXY environment variables, while PySocks is not installed in the environment. It fires lazily: only when proxy_manager_for constructs a SOCKSProxyManager for the SOCKS scheme, never at import time.

Common situations: Most common cause is installing requests via a minimal extras spec that omits the socks extra, or deploying a fresh virtualenv/CI image where 'pip install requests' was run without 'requests[socks]'. Also seen after dependency-pin lock-file updates that drop PySocks, or when copying a working proxy config to a new container that lacks the wheel.

Related errors


AI-assisted analysis of psf/requests@8068356288 (2026-08-11). Data as JSON: /api/errors/7d0cbb8d13fd92f5. Report an issue: GitHub.

Appendix: source

Thrown at src/requests/adapters.py:67

    SSLError,
)
from .models import Response
from .structures import CaseInsensitiveDict
from .utils import (
    DEFAULT_CA_BUNDLE_PATH,
    get_auth_from_url,
    get_encoding_from_headers,
    prepend_scheme_if_needed,
    select_proxy,
    urldefragauth,
)

try:
    from urllib3.contrib.socks import SOCKSProxyManager  # type: ignore[assignment]
except ImportError:

    def SOCKSProxyManager(*args: Any, **kwargs: Any) -> None:
        raise InvalidSchema("Missing dependencies for SOCKS support.")


if typing.TYPE_CHECKING:
    from urllib3.connectionpool import HTTPConnectionPool
    from urllib3.poolmanager import PoolManager as _PoolManager

    from . import _types as _t
    from .models import PreparedRequest

from ._types import is_prepared as _is_prepared

DEFAULT_POOLBLOCK = False
DEFAULT_POOLSIZE = 10
DEFAULT_RETRIES = 0
DEFAULT_POOL_TIMEOUT = None


def _urllib3_request_context(

View on GitHub (pinned to 8068356288)