{"record":{"id":"bd94d219bd41af40","repo":"python/cpython","slug":"socket-cannot-be-of-type-sslsocket","errorCode":null,"errorMessage":"Socket cannot be of type SSLSocket","messagePattern":"Socket cannot be of type SSLSocket","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"Lib/asyncio/base_events.py","lineNumber":207,"sourceCode":"            # stop it.\n            return\n    futures._get_loop(fut).stop()\n\n\nif hasattr(socket, 'TCP_NODELAY'):\n    def _set_nodelay(sock):\n        if (sock.family in {socket.AF_INET, socket.AF_INET6} and\n                sock.type == socket.SOCK_STREAM and\n                sock.proto == socket.IPPROTO_TCP):\n            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\nelse:\n    def _set_nodelay(sock):\n        pass\n\n\ndef _check_ssl_socket(sock):\n    if ssl is not None and isinstance(sock, ssl.SSLSocket):\n        raise TypeError(\"Socket cannot be of type SSLSocket\")\n\n\nclass _SendfileFallbackProtocol(protocols.Protocol):\n    def __init__(self, transp):\n        if not isinstance(transp, transports._FlowControlMixin):\n            raise TypeError(\"transport should be _FlowControlMixin instance\")\n        self._transport = transp\n        self._proto = transp.get_protocol()\n        self._should_resume_reading = transp.is_reading()\n        self._should_resume_writing = transp._protocol_paused\n        transp.pause_reading()\n        transp.set_protocol(self)\n        if self._should_resume_writing:\n            self._write_ready_fut = self._transport._loop.create_future()\n        else:\n            self._write_ready_fut = None\n\n    async def drain(self):","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/asyncio/base_events.py#L189-L225","documentation":"_check_ssl_socket is called by asyncio transports/servers (e.g. loop.create_connection and loop.create_server) whenever a pre-made sock is supplied together with an ssl context. asyncio implements TLS itself via ssl protocols and requires a plain socket; passing an already-wrapped ssl.SSLSocket would double-handshake and corrupt the protocol, so it raises TypeError immediately.","triggerScenarios":"s = sslctx.wrap_socket(raw_sock) followed by await loop.create_connection(proto, sock=s, ssl=sslctx); similarly create_server(..., sock=wrapped) or sock_* helpers handed an SSLSocket. Also occurs when a socket obtained from some library already performs TLS (e.g. a tunnel library) and is then forwarded to asyncio with ssl set.","commonSituations":"Upgrading plain-socket code to TLS by wrapping the socket manually (the intuitive but wrong approach); libraries that hand out connected SSLSocket objects that are then fed to asyncio; mixing blocking ssl module usage with asyncio's async TLS layer.","solutions":["Pass the raw, unwrapped socket and the SSLContext: loop.create_connection(proto, sock=raw_sock, ssl=sslctx) — asyncio does the handshake asynchronously.","If the socket is already TLS-wrapped by other code, pass ssl=None and treat the stream as already secure (and avoid blocking wrap_socket in async code).","In async code, replace sslctx.wrap_socket with asyncio's ssl= parameter or await loop.start_tls(...) for upgrading in place."],"exampleFix":"# before\nwrapped = ssl_ctx.wrap_socket(raw_sock, server_hostname='example.com')\nreader, writer = await asyncio.open_connection(sock=wrapped, ssl=ssl_ctx)\n# TypeError: Socket cannot be of type SSLSocket\n\n# after\nreader, writer = await asyncio.open_connection(\n    sock=raw_sock, ssl=ssl_ctx, server_hostname='example.com')","handlingStrategy":"type-guard","validationCode":"import socket, ssl\n\ndef check_not_ssl_socket(sock):\n    if isinstance(sock, ssl.SSLSocket):\n        raise TypeError('pass the raw socket plus ssl=SSLContext to asyncio')\n    return sock","typeGuard":"import ssl\n\ndef is_plain_socket(sock) -> bool:\n    return not (ssl and isinstance(sock, ssl.SSLSocket))","tryCatchPattern":"try:\n    reader, writer = await asyncio.open_connection(sock=sock, ssl=ctx)\nexcept TypeError as e:\n    if 'SSLSocket' in str(e):\n        # unwrap is impossible; fix the caller: pass raw sock + ssl=ctx\n        raise RuntimeError('do not pre-wrap sockets; pass ssl=SSLContext') from None","preventionTips":["Never call ssl_ctx.wrap_socket in asyncio code paths; pass ssl=ctx to the asyncio API.","Type-annotate parameters as socket.socket and assert not SSLSocket at boundaries.","Use await loop.start_tls(...) when you must upgrade an established plain connection."],"tags":["asyncio","ssl","tls","sockets","typeerror"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}