aio-libs/aiohttp · error · ClientConnectorSSLError
Cannot connect to host {host}:{port} ssl:{ssl} [{strerror}]
Error message
Cannot connect to host {host}:{port} ssl:{ssl} [{strerror}] What it means
Raised inside _wrap_create_connection() when the TLS handshake raises an `ssl_errors` exception (ssl.SSLError / ssl.SSLError subclasses that are not certificate errors) during a direct connection. Wrapped as ClientConnectorSSLError(req.connection_key, exc). Typically indicates a protocol/cipher mismatch or handshake abort rather than a certificate-trust problem.
Source
Thrown at aiohttp/connector.py:1349
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,
# which is standard TLS and works on all event loops and Python versions.
if req.proxy is None or req.proxy.scheme != "https":View on GitHub (pinned to c0ef574e29)
Solutions
- Verify the URL scheme matches what the server speaks (`http://` vs `https://`).
- Inspect the wrapped OSError via `traceback.print_exc()` for the SSL reason string.
- Adjust the SSLContext min/max version and cipher list to what the server supports.
- Update the Python/OpenSSL build if the failure is `unsupported protocol`.
Example fix
# before ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.maximum_version = ssl.TLSVersion.TLSv1 # after ctx = ssl.create_default_context() ctx.minimum_version = ssl.TLSVersion.TLSv1_2
Defensive patterns
Strategy: try-catch
Validate before calling
import ssl
def modern_tls_context() -> ssl.SSLContext:
ctx = ssl.create_default_context()
ctx.minimum_version = ssl.TLSVersion.TLSv1_2
return ctx Try / catch
from aiohttp import ClientConnectorSSLError
try:
await session.get(url, ssl=ctx)
except ClientConnectorSSLError as e:
# log e.__cause__ for the OpenSSL reason string
raise Prevention
- Default to ssl.create_default_context() unless you have a specific reason to restrict it.
- Verify URL scheme matches the service (http vs https) before issuing.
- Keep your Python/OpenSSL build current to avoid obsolete protocol ceilings.
When it happens
Trigger: Server supports only outdated TLS versions/ciphers, the SSLContext is misconfigured (e.g. min/max version wrong), the server abruptly closed the socket during handshake, or a non-TLS service answered on port 443.
Common situations: Forcing TLSv1.0 on a TLSv1.3-only server. Restrictive cipher suite on the client. Connecting plain HTTP to an HTTPS URL/port. Middleboxes terminating TLS incorrectly. Old OpenSSL linked into Python.
Related errors
- Cannot connect to host {host}:{port} ssl:{ssl} [{ClassName}:
- Cannot initialize a TLS-in-TLS connection to host {req.url.h
- Invalid window size
- Extension for deflate not supported{ext}
- ssl should be SSLContext, Fingerprint, or bool, got {ssl!r}
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/71487353ecf56bac.json.
Report an issue: GitHub.