{"record":{"id":"733b0597730e40df","repo":"aio-libs/aiohttp","slug":"cannot-initialize-a-tls-in-tls-connection-to-host","errorCode":null,"errorMessage":"Cannot initialize a TLS-in-TLS connection to host {req.url.host!s}:{req.url.port:d} through an underlying connection to an HTTPS proxy {req.proxy!s} ssl:{req.ssl or 'default'} [{type_err!s}]","messagePattern":"Cannot initialize a TLS-in-TLS connection to host (.+?):(.+?) through an underlying connection to an HTTPS proxy (.+?) ssl:(.+?) \\[(.+?)\\]","errorType":"exception","errorClass":"ClientConnectionError","httpStatus":null,"severity":"error","filePath":"aiohttp/connector.py","lineNumber":1480,"sourceCode":"                        except ServerFingerprintMismatch:\n                            tls_transport.close()\n                            if not self._cleanup_closed_disabled:\n                                self._cleanup_closed_transports.append(tls_transport)\n                            raise\n        except cert_errors as exc:\n            raise ClientConnectorCertificateError(req.connection_key, exc) from exc\n        except ssl_errors as exc:\n            raise ClientConnectorSSLError(req.connection_key, exc) from exc\n        except OSError as exc:\n            if exc.errno is None and isinstance(exc, asyncio.TimeoutError):\n                raise\n            raise client_error(req.connection_key, exc) from exc\n        except TypeError as type_err:\n            # Example cause looks like this:\n            # TypeError: transport <asyncio.sslproto._SSLProtocolTransport\n            # object at 0x7f760615e460> is not supported by start_tls()\n\n            raise ClientConnectionError(\n                \"Cannot initialize a TLS-in-TLS connection to host \"\n                f\"{req.url.host!s}:{req.url.port:d} through an underlying connection \"\n                f\"to an HTTPS proxy {req.proxy!s} ssl:{req.ssl or 'default'} \"\n                f\"[{type_err!s}]\"\n            ) from type_err\n        else:\n            if tls_transport is None:\n                msg = \"Failed to start TLS (possibly caused by closing transport)\"\n                raise client_error(req.connection_key, OSError(msg))\n            tls_proto.connection_made(\n                tls_transport\n            )  # Kick the state machine of the new TLS protocol\n\n        return tls_transport, tls_proto\n\n    def _convert_hosts_to_addr_infos(\n        self, hosts: list[ResolveResult]\n    ) -> list[AddrInfoType]:","sourceCodeStart":1462,"sourceCodeEnd":1498,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/connector.py#L1462-L1498","documentation":"Raised from _start_tls_connection when start_tls() raises TypeError - historically because the underlying asyncio transport does not support start_tls (the stdlib asyncio SSL transport could not be re-upgraded before Python 3.11, bpo-44011). aiohttp catches the TypeError and re-raises it as ClientConnectionError with the explicit 'Cannot initialize a TLS-in-TLS connection' message so the cause is obvious. It is the hard-failure counterpart of the runtime warning emitted by _warn_about_tls_in_tls.","triggerScenarios":"HTTPS request through an HTTPS proxy on Python < 3.11 with the default asyncio loop; using a custom event loop whose transport lacks start_tls support; uvloop/aiofastnet absent so the stdlib limitation applies.","commonSituations":"Legacy Python runtime forced to do TLS-in-TLS; corporate HTTPS-proxy-only egress on an older interpreter; event loop without start_tls-compatible transports.","solutions":["Upgrade to Python 3.11+ where asyncio natively supports TLS-in-TLS.","Switch to uvloop (or aiofastnet if available) - their transports advertise start_tls compatibility.","Reconfigure egress to use an HTTP (CONNECT) proxy so only one TLS layer is needed.","Avoid chaining an HTTPS target through an HTTPS proxy if the runtime cannot satisfy TLS-in-TLS."],"exampleFix":"# before - Python 3.10, default asyncio\nawait session.get('https://target/', proxy='https://corp-proxy:443')\n# after - use an HTTP proxy instead\nawait session.get('https://target/', proxy='http://corp-proxy:8080')\n# or upgrade to Python 3.11+ / install uvloop","handlingStrategy":"fallback","validationCode":"import sys\n\ndef can_tls_in_tls() -> bool:\n    return sys.version_info >= (3, 11)\n\nif not can_tls_in_tls() and proxy_url.startswith('https://'):\n    raise RuntimeError('use an HTTP proxy or upgrade to Python 3.11+ for HTTPS-over-HTTPS')","typeGuard":"null","tryCatchPattern":"try:\n    resp = await session.get(url, proxy=proxy_url)\nexcept aiohttp.ClientConnectionError as exc:\n    if 'TLS-in-TLS' in str(exc):\n        # fallback to an HTTP proxy (single TLS layer)\n        http_proxy = proxy_url.replace('https://', 'http://')\n        resp = await session.get(url, proxy=http_proxy)\n    else:\n        raise","preventionTips":["Prefer an HTTP CONNECT proxy when the runtime cannot do TLS-in-TLS.","Target Python 3.11+ or install uvloop for environments that need HTTPS-over-HTTPS proxying.","Heed the runtime warning from _warn_about_tls_in_tls before it becomes this hard error."],"tags":["ssl","proxy","tls-in-tls","python-version","event-loop"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}