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.

  1. Read the text after 'Caused by' at the end of the message.
  2. Failed to resolve: check the hostname and resolve it from the same machine or container.
  3. Connection refused: check the port and that the service is running and listening on that interface.
  4. Timed out: check firewalls, security groups and whether the host is reachable from this network.
  5. Add timeout= to every call, and add retries with backoff only for idempotent requests.
python
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.

Plans from $29/moSee what your agent readsSee the setupCancel any time from the billing portal

Related errors

References: Requests: Timeouts, urllib3: Retry