requests.exceptions.ConnectionError: HTTPSConnectionPool(host='api.example.com', port=443): Max retries exceeded with url: /v1/items
Python · updated 2026-11-02
Raised by requests when urllib3 cannot open or keep a connection to the host. "Max retries exceeded" is misleading: by default requests does not retry, so it usually means one failed attempt. The part that matters is the reason in parentheses at the end, such as NameResolutionError, ConnectionRefusedError or a timeout.
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='billing.internal', port=443): Max retries exceeded with url: /v1/invoices (Caused by NameResolutionError( "<urllib3.connection.HTTPSConnection object at 0x7f9c2c1d5e50>: Failed to resolve 'billing.internal' ([Errno -2] Name or service not known)"))
Quick fix
Read the 'Caused by' part and fix that: Failed to resolve means DNS or a wrong hostname, Connection refused means nothing is listening on that host and port, a timeout means the host is unreachable or slow, and SSLError means a certificate problem. Always pass a timeout to requests so a dead host fails fast instead of hanging a worker.
- Read the text after 'Caused by' at the end of the message.
- Failed to resolve: check the hostname and resolve it from the same machine or container.
- Connection refused: check the port and that the service is running and listening on that interface.
- Timed out: check firewalls, security groups and whether the host is reachable from this network.
- Add timeout= to every call, and add retries with backoff only for idempotent requests.
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
retry = Retry(total=3, backoff_factor=0.5, status_forcelist=[502, 503, 504],
allowed_methods=["GET", "HEAD"])
session.mount("https://", HTTPAdapter(max_retries=retry))
resp = session.get("https://api.example.com/v1/items", timeout=(3.05, 15))
resp.raise_for_status()Why it happens
DNS could not resolve the host
NameResolutionError or "Name or service not known": a typo, an unset env var, or an internal hostname used from a network where it does not exist.
Nothing listening on that host and port
ConnectionRefusedError ([Errno 111]): the service is down, still starting, bound to localhost only, or the port is wrong.
Network unreachable or too slow
ConnectTimeoutError or "Network is unreachable": a firewall, security group or missing route, or a host that is overloaded.
TLS problem
SSLError inside the message: an expired or self-signed certificate, a hostname mismatch, or an outdated CA bundle on the machine.
Rate limiting or a proxy in the way
A proxy from HTTP(S)_PROXY env vars that is down, or a remote side dropping connections under load, shows up as a connection error rather than an HTTP status.
Other fixes
- Never call requests without timeout=; the default is to wait forever.
- Retry only idempotent methods, with backoff, and log the final cause when retries run out.
- Validate service URLs at startup so a missing env var fails the deploy instead of every request.
Same error, other wording
- requests.exceptions.ConnectionError: ... (Caused by NewConnectionError(... [Errno 111] Connection refused'))
- requests.exceptions.ConnectTimeout: ... (Caused by ConnectTimeoutError(...))
- requests.exceptions.SSLError: ... Max retries exceeded with url: ... (Caused by SSLError(...))
Let your coding agent catch the next one
Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:
> Find the requests ConnectionError / Max retries exceeded errors in production, group them by host and by the 'Caused by' reason, and say for each whether it is DNS, a refused port, a timeout or TLS, with the release behind the latest one.
Related errors
- AttributeError: 'NoneType' object has no attribute 'x'
- KeyError: 'email'
- UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
References: Requests: Timeouts, urllib3: Retry