pypa/pip · error · ConnectionFailedError
connection-failed
connection-failed
Error message
Failed to connect to {host} while fetching {url} What it means
Raised as ConnectionFailedError (the not-MaxRetryError fallback) when the connection error's reason is neither a urllib3 TimeoutError, SSLError, nor a MaxRetryError. It is the generic catch-all for unrecognized connection-layer failures during non-streamed responses, with message 'Failed to connect to {host} while fetching {url}'.
Solutions
- Read the wrapped error details pip prints for the underlying cause.
- Verify host reachability and DNS resolution.
- Retry the install; transient resets often clear.
- Check for an outdated or mismatched urllib3/requests and update pip.
Defensive patterns
Strategy: try-catch
Validate before calling
import socket
def host_resolves_and_connects(host: str, port: int = 443) -> bool:
try:
socket.getaddrinfo(host, port)
with socket.create_connection((host, port), timeout=5):
return True
except OSError:
return False Try / catch
from pip._internal.exceptions import ConnectionFailedError
try:
run_pip_install(["pkg"])
except ConnectionFailedError:
# inspect details, verify DNS/network, then retry
run_pip_install(["pkg"]) Prevention
- Verify DNS resolution and outbound connectivity before installs.
- Keep urllib3/requests versions consistent (use pip's vendored copies).
- Retry after confirming the underlying cause from pip's printed context.
When it happens
Trigger: A requests.ConnectionError surfaces whose underlying reason does not fit the known urllib3 exception types (not timeout, not SSL, not MaxRetryError), e.g. an unexpected OS-level socket error or a novel urllib3 exception.
Common situations: DNS mis-resolution, connection reset, intermittent OS-level socket errors, library/urllib3 version mismatches surfacing new exception types.
Related errors
- connection-timeout
- proxy-connection-failed
- Could not install requirement
- Error reading pylock file
- incomplete-download
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/b2f6fe3ba5390da5.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/network/utils.py:184
url = redact_auth_from_url(url)
raw_hostname = urlsplit(url).hostname or urlsplit(url).netloc
reason = error.args[0] if error.args else error
# NewConnectionError is a subclass of TimeoutError for some reason...
if isinstance(reason, urllib3.exceptions.TimeoutError) and not isinstance(
reason, urllib3.exceptions.NewConnectionError
):
# A bare timeout error can occur during non-streamed responses. Don't
# ask me how.
_raise_timeout_error(reason, url, raw_hostname, timeout)
if isinstance(reason, urllib3.exceptions.SSLError):
# A bare SSL error can occur during non-streamed responses, after the
# initial connection and TLS handshake have completed.
raise SSLVerificationError(url, raw_hostname, reason)
# At this point, all errors should be wrapped in MaxRetryError.
if not isinstance(reason, urllib3.exceptions.MaxRetryError):
raise ConnectionFailedError(url, raw_hostname, reason)
max_retry_error = reason
assert isinstance(max_retry_error.pool, urllib3.connectionpool.HTTPConnectionPool)
host = max_retry_error.pool.host
proxy = max_retry_error.pool.proxy
# Narrow the reason further to the specific error from the last retry.
reason = max_retry_error.reason
if isinstance(reason, urllib3.exceptions.SSLError):
raise SSLVerificationError(url, host, reason)
if isinstance(reason, urllib3.exceptions.TimeoutError) and not isinstance(
reason, urllib3.exceptions.NewConnectionError
):
_raise_timeout_error(reason, url, host, timeout)
if isinstance(reason, urllib3.exceptions.ProxyError):
assert proxy is not None
raise ProxyConnectionError(url, redact_auth_from_url(str(proxy)), reason)
View on GitHub (pinned to f399c37189)