Main Ecosystems
HomePython CorePandas ReferenceNumPy ScientificFastAPI & PydanticDjango Enterprise
More Ecosystems
Environment & SetupRequests & HTTPAsyncIO ConcurrencyObject-Oriented OOPPyTorch Deep LearningScikit-Learn MLFlask FrameworkWeb ScrapingDatabase & ORMDevOps & Docker

requests.exceptions.ConnectionError: Failed to establish a new connection

Verified FixPython 3.10+Requests 2.31+Silo: requests

Quick Fix / Solution Rapide

Wrap network calls in a try/except RequestException block with explicit timeout settings and an HTTPAdapter retry strategy.

Root Cause Analysis

This error occurs when Python tries to open a TCP socket connection to a remote server, but the underlying network stack cannot establish the handshake due to DNS resolution failures, unreachable hosts, or firewall rules.

1. Network Layer vs Application Layer

When requests.get() is invoked, urllib3 attempts to resolve the domain name via DNS, acquire an IP address, and initiate a TCP 3-way handshake on the target port. If the host cannot be resolved (NXDOMAIN) or the destination server drops SYN packets, urllib3 raises a MaxRetryError enclosing a socket gaierror or ConnectionRefusedError, which requests bubbles up as requests.exceptions.ConnectionError.

2. Common Causes in Production

In production environments, ConnectionError is typically caused by: (1) misspelled domain names or invalid port numbers, (2) corporate proxies and missing HTTP_PROXY environment variables, (3) target services being offline, or (4) security firewalls blocking outbound traffic.

3. Contrast with Other HTTP Errors

ConnectionError indicates that no HTTP communication ever took place—the client never reached the server. In contrast, HTTPError (like 404 Not Found or 500 Internal Server Error) indicates that the TCP handshake succeeded and the remote web server responded with an HTTP status code. Timeout indicates that the connection or read operation exceeded the configured deadline.

4. Note de Reproductibilité

Cette erreur dépend de l'état du réseau, de la connectivité Internet, de la résolution DNS locale et de la disponibilité des serveurs distants. Elle ne peut pas être reproduite de manière déterministe dans un environnement de test unitaire isolé sans dépendance réseau externe.

Reproduction Code (MCVE)

Example: Bug Reproduction
import requests

# Attempting to connect to an unreachable local address triggers ConnectionError
response = requests.get('http://127.0.0.1:59999/health', timeout=1.0)

Solution 1: Robust Exception Handling with Timeout Configuration

Always configure an explicit tuple timeout (connect_timeout, read_timeout) and catch requests.exceptions.RequestException to handle connection drops gracefully.

Example: Recommended Solution
import requests
from requests.exceptions import ConnectionError, Timeout, RequestException

target_url = 'http://127.0.0.1:59999/health'

try:
    response = requests.get(target_url, timeout=(2.0, 5.0))
    response.raise_for_status()
    print('Status:', response.status_code)
except ConnectionError as e:
    print(f'Handled connection failure: remote service is unreachable ({e.__class__.__name__})')
except Timeout:
    print('Request timed out.')
except RequestException as e:
    print(f'General HTTP request exception: {e}')

Solution 2: Configure Automatic Retries with urllib3 HTTPAdapter

Mount an HTTPAdapter configured with exponential backoff on a requests.Session to automatically retry transient connection failures.

Example: Alternative Solution
import requests
from urllib3.util import Retry
from requests.adapters import HTTPAdapter

session = requests.Session()
retries = Retry(
    total=3,
    backoff_factor=0.5,
    status_forcelist=[500, 502, 503, 504],
    raise_on_status=False
)
adapter = HTTPAdapter(max_retries=retries)
session.mount('http://', adapter)
session.mount('https://', adapter)

print('Session configured with resilient HTTPAdapter.')

A dangerous practice in production code is catching bare except Exception: and proceeding blindly without verifying response integrity. Always distinguish between ConnectionError (client could not reach server) and HTTPError (server reached and returned error code). Another common pitfall is omitting the timeout parameter: requests with no timeout can hang indefinitely if the socket remains open without sending data. In containerized Docker setups, using localhost or 127.0.0.1 inside a container refers to the container itself rather than the host machine.