{"record":{"id":"68a80e14d98026e0","repo":"python/cpython","slug":"you-must-set-server-hostname-when-using-ssl-withou","errorCode":null,"errorMessage":"You must set server_hostname when using ssl without a host","messagePattern":"You must set server_hostname when using ssl without a host","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/asyncio/base_events.py","lineNumber":1101,"sourceCode":"        connection in the background.  When successful, the coroutine\n        returns a (transport, protocol) pair.\n        \"\"\"\n        if server_hostname is not None and not ssl:\n            raise ValueError('server_hostname is only meaningful with ssl')\n\n        if server_hostname is None and ssl:\n            # Use host as default for server_hostname.  It is an error\n            # if host is empty or not set, e.g. when an\n            # already-connected socket was passed or when only a port\n            # is given.  To avoid this error, you can pass\n            # server_hostname='' -- this will bypass the hostname\n            # check.  (This also means that if host is a numeric\n            # IP/IPv6 address, we will attempt to verify that exact\n            # address; this will probably fail, but it is possible to\n            # create a certificate for a specific IP address, so we\n            # don't judge it here.)\n            if not host:\n                raise ValueError('You must set server_hostname '\n                                 'when using ssl without a host')\n            server_hostname = host\n\n        if ssl_handshake_timeout is not None and not ssl:\n            raise ValueError(\n                'ssl_handshake_timeout is only meaningful with ssl')\n\n        if ssl_shutdown_timeout is not None and not ssl:\n            raise ValueError(\n                'ssl_shutdown_timeout is only meaningful with ssl')\n\n        if sock is not None:\n            _check_ssl_socket(sock)\n\n        if happy_eyeballs_delay is not None and interleave is None:\n            # If using happy eyeballs, default to interleave addresses by family\n            interleave = 1\n","sourceCodeStart":1083,"sourceCodeEnd":1119,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/asyncio/base_events.py#L1083-L1119","documentation":"Raised by create_connection when ssl is enabled but no host name is available to use as the TLS server_hostname. When server_hostname is omitted, asyncio defaults it to `host`; if host is empty/None (typical when connecting via a pre-made socket or only a port), certificate verification has nothing to verify against, so it refuses. Passing server_hostname='' explicitly bypasses the hostname check.","triggerScenarios":"Calling create_connection(proto, None, None, sock=s, ssl=ctx) — an already-connected socket with TLS but no server_hostname. Also create_connection(proto, '', 443, ssl=ctx).","commonSituations":"Wrapping an already-accepted/tunnelled socket (e.g. from a proxy CONNECT or a test harness) in TLS without naming the target; migrating code that used loop.sock_connect + manual SSL transport.","solutions":["Pass server_hostname explicitly: create_connection(proto, None, None, sock=s, ssl=ctx, server_hostname='example.com').","If you deliberately want no hostname verification (rare, insecure), pass server_hostname=''.","Otherwise supply host (and port) instead of a raw socket so asyncio can derive the name."],"exampleFix":"// before\ntransport, proto = await loop.create_connection(\n    factory, None, None, sock=raw_sock, ssl=ctx)  # ValueError\n\n// after\ntransport, proto = await loop.create_connection(\n    factory, None, None, sock=raw_sock, ssl=ctx,\n    server_hostname='api.example.com')","handlingStrategy":"validation","validationCode":"if ssl_ctx is not None and not host and not server_hostname:\n    raise ConfigError('server_hostname required when using ssl without a host')","typeGuard":null,"tryCatchPattern":"try:\n    tp, pr = await loop.create_connection(proto, None, None, sock=s, ssl=ctx)\nexcept ValueError as e:\n    if 'server_hostname' not in str(e):\n        raise\n    tp, pr = await loop.create_connection(proto, None, None, sock=s, ssl=ctx,\n                                          server_hostname=expected_name)","preventionTips":["When adopting raw sockets for TLS, always carry the intended peer name alongside the socket.","Never pass empty host '' with ssl unless you also set server_hostname explicitly.","Encapsulate socket+ssl+hostname in one connection-spec object so they travel together."],"tags":["asyncio","tls","ssl","certificate-verification","validation"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}