python/cpython · error · ValueError
server_hostname is only meaningful with ssl
Error message
server_hostname is only meaningful with ssl
What it means
Raised by BaseEventLoop.create_connection when the caller passes server_hostname together with ssl=None/False. server_hostname is only used to verify the TLS peer's certificate; without an ssl context/protocol there is no certificate check, so the argument is meaningless and asyncio rejects it to catch configuration mistakes.
Source
Thrown at Lib/asyncio/base_events.py:1087
proto=0, flags=0, sock=None,
local_addr=None, server_hostname=None,
ssl_handshake_timeout=None,
ssl_shutdown_timeout=None,
happy_eyeballs_delay=None, interleave=None,
all_errors=False):
"""Connect to a TCP server.
Create a streaming transport connection to a given internet host and
port: socket family AF_INET or socket.AF_INET6 depending on host (or
family if specified), socket type SOCK_STREAM. protocol_factory must
be a callable returning a protocol instance.
This method is a coroutine which will try to establish the
connection in the background. When successful, the coroutine
returns a (transport, protocol) pair.
"""
if server_hostname is not None and not ssl:
raise ValueError('server_hostname is only meaningful with ssl')
if server_hostname is None and ssl:
# Use host as default for server_hostname. It is an error
# if host is empty or not set, e.g. when an
# already-connected socket was passed or when only a port
# is given. To avoid this error, you can pass
# server_hostname='' -- this will bypass the hostname
# check. (This also means that if host is a numeric
# IP/IPv6 address, we will attempt to verify that exact
# address; this will probably fail, but it is possible to
# create a certificate for a specific IP address, so we
# don't judge it here.)
if not host:
raise ValueError('You must set server_hostname '
'when using ssl without a host')
server_hostname = host
if ssl_handshake_timeout is not None and not ssl:View on GitHub (pinned to bc6749cc3b)
Solutions
- Pass an ssl context: ssl=ssl.create_default_context() alongside server_hostname.
- If the connection is intentionally plaintext, drop server_hostname from the call.
- Build kwargs conditionally: kwargs['server_hostname'] = name only when ssl is set.
Example fix
// before
await loop.create_connection(proto, host, port, server_hostname='example.com') # no ssl
// after
kwargs = {}
if use_tls:
kwargs['ssl'] = ssl.create_default_context()
kwargs['server_hostname'] = 'example.com'
await loop.create_connection(proto, host, port, **kwargs) Defensive patterns
Strategy: validation
Validate before calling
if server_hostname is not None and not ssl_ctx:
raise ConfigError('server_hostname requires an ssl context') Try / catch
try:
await loop.create_connection(proto, host, port, server_hostname=name)
except ValueError as e:
if 'only meaningful with ssl' not in str(e):
raise
await loop.create_connection(proto, host, port,
ssl=ssl.create_default_context(),
server_hostname=name) Prevention
- Build TLS kwargs (ssl, server_hostname, both timeouts) as one atomic dict — set all or none.
- Lint for create_connection calls that pass server_hostname without ssl=.
- In feature-flagged TLS, branch on the flag before composing kwargs.
When it happens
Trigger: Calling loop.create_connection(factory, host, port, server_hostname='example.com') with no ssl= argument (ssl defaults to None). Common when TLS support was removed or made conditional but the hostname argument stayed.
Common situations: Feature-flagged TLS: code built the server_hostname string eagerly but passed ssl=None in the plaintext branch; refactors that dropped the ssl argument; testing against a local plaintext server with leftover TLS kwargs.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- You must set server_hostname when using ssl without a host
- ssl_handshake_timeout is only meaningful with ssl
- ssl_shutdown_timeout is only meaningful with ssl
- sslcontext is expected to be an instance of ssl.SSLContext,
- Socket cannot be of type SSLSocket
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/15e3592ab33cce3f.
Report an issue: GitHub.