aio-libs/aiohttp · error · ClientConnectorCertificateError
Cannot connect to host {host}:{port} ssl:{ssl} [{ClassName}:
Error message
Cannot connect to host {host}:{port} ssl:{ssl} [{ClassName}: {args}] What it means
Raised inside _wrap_create_connection() when the underlying asyncio create_connection() raises an exception matching `cert_errors` (e.g. ssl.SSLCertVerificationError, ssl.CertificateError) during the initial direct TLS handshake. Wrapped as ClientConnectorCertificateError(req.connection_key, exc), carrying the host/port/SSL config of the failed request.
Source
Thrown at aiohttp/connector.py:1347
):
sock = await aiohappyeyeballs.start_connection(
addr_infos=addr_infos,
local_addr_infos=self._local_addr_infos,
happy_eyeballs_delay=self._happy_eyeballs_delay,
interleave=self._interleave,
loop=self._loop,
socket_factory=self._socket_factory,
)
# Add ssl_shutdown_timeout for Python 3.11+ when SSL is used
if (
kwargs.get("ssl")
and self._ssl_shutdown_timeout
and sys.version_info >= (3, 11)
):
kwargs["ssl_shutdown_timeout"] = self._ssl_shutdown_timeout
return await create_connection(self._loop, *args, **kwargs, sock=sock)
except cert_errors as exc:
raise ClientConnectorCertificateError(req.connection_key, exc) from exc
except ssl_errors as exc:
raise ClientConnectorSSLError(req.connection_key, exc) from exc
except OSError as exc:
if exc.errno is None and isinstance(exc, asyncio.TimeoutError):
raise
raise client_error(req.connection_key, exc) from exc
def _warn_about_tls_in_tls(
self,
underlying_transport: asyncio.Transport,
req: ClientRequest,
) -> None:
"""Issue a warning if the requested URL has HTTPS scheme."""
if req.url.scheme != "https":
return
# TLS-in-TLS only applies when the proxy itself is HTTPS.
# When the proxy is HTTP, start_tls upgrades a plain TCP connection,View on GitHub (pinned to c0ef574e29)
Solutions
- Install the correct CA bundle (e.g. `certifi`, or your corporate root) into the trust store.
- Provide a custom `ssl.SSLContext` with the right CA loaded: `ssl.create_default_context(cafile=...)`.
- For dev only, pass `ssl=False` to disable verification (never in production).
- Check system time with `date` and fix clock skew.
Example fix
# before
async with session.get('https://self-signed.example') as r: ...
# after (dev only)
import ssl
ctx = ssl.create_default_context(cadata=PEM_CERT)
# or, dev-only bypass:
async with session.get('https://self-signed.example', ssl=False) as r: ... Defensive patterns
Strategy: try-catch
Validate before calling
import ssl
def trusted_context(cafile=None, cadata=None) -> ssl.SSLContext:
ctx = ssl.create_default_context(cafile=cafile, cadata=cadata)
return ctx Try / catch
from aiohttp import ClientConnectorCertificateError
try:
await session.get(url, ssl=ctx)
except ClientConnectorCertificateError as e:
# e.g. install missing CA or pin fingerprint; do not blind-bypass in prod
raise Prevention
- Always build an explicit SSLContext with the right CA bundle for the deployment.
- In dev, gate ssl=False behind an env var that is fatal in production.
- Monitor cert expiry of internal CAs feeding your trust store.
When it happens
Trigger: Direct (non-proxy) HTTPS connection where the server certificate fails verification: self-signed cert, expired cert, wrong hostname, untrusted CA, or a pinned-fingerprint mismatch during the handshake.
Common situations: Self-signed dev/staging servers. Corporate MITM proxies with an untrusted CA. System clock skew making a valid cert look expired. Missing CA bundle on minimal containers. Hostname mismatch behind a CDN.
Related errors
- Cannot connect to host {host}:{port} ssl:{ssl} [{strerror}]
- Cannot initialize a TLS-in-TLS connection to host {req.url.h
- ssl should be SSLContext, Fingerprint, or bool, got {ssl!r}
- fingerprint has invalid length
- md5 and sha1 are insecure and not supported. Use sha256.
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/a9cf1211ab852708.json.
Report an issue: GitHub.