RustPython/RustPython · error · ValueError
ssl_shutdown_timeout is only meaningful with ssl
Error message
ssl_shutdown_timeout is only meaningful with ssl
What it means
ValueError from BaseEventLoop.create_connection: ssl_shutdown_timeout (seconds allowed for the TLS shutdown/close_notify phase, added in Python 3.11+) was supplied while ssl is falsy. Like ssl_handshake_timeout it only applies to the TLS lifecycle, so asyncio rejects it on plaintext connections.
Source
Thrown at Lib/asyncio/base_events.py:1104
# 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:
raise ValueError(
'ssl_handshake_timeout is only meaningful with ssl')
if ssl_shutdown_timeout is not None and not ssl:
raise ValueError(
'ssl_shutdown_timeout is only meaningful with ssl')
if sock is not None:
_check_ssl_socket(sock)
if happy_eyeballs_delay is not None and interleave is None:
# If using happy eyeballs, default to interleave addresses by family
interleave = 1
if host is not None or port is not None:
if sock is not None:
raise ValueError(
'host/port and sock can not be specified at the same time')
infos = await self._ensure_resolved(
(host, port), family=family,
type=socket.SOCK_STREAM, proto=proto, flags=flags, loop=self)
if not infos:View on GitHub (pinned to aaeab4f754)
Solutions
- Remove ssl_shutdown_timeout from non-TLS calls
- Enable TLS with ssl=<SSLContext> so the shutdown timeout applies
- Gate the kwarg: kwargs = {'ssl_shutdown_timeout': 5} if ctx else {}
Example fix
# before
await loop.create_connection(proto, 'example.com', 80,
ssl_shutdown_timeout=5.0)
# after
kwargs = {'ssl_shutdown_timeout': 5.0} if ssl_ctx else {}
await loop.create_connection(proto, 'example.com', 80, ssl=ssl_ctx, **kwargs) Defensive patterns
Strategy: validation
Validate before calling
kwargs = {}
if ssl_ctx is not None:
kwargs['ssl_shutdown_timeout'] = 5.0
kwargs['ssl'] = ssl_ctx
await loop.create_connection(proto, host, port, **kwargs) Prevention
- Remember ssl_shutdown_timeout is 3.11+; gate it by TLS being enabled
- Never splat a full TLS settings dict into non-TLS calls
- Key your settings objects by scheme (https vs http), not one generic blob
When it happens
Trigger: await loop.create_connection(proto, host, 80, ssl_shutdown_timeout=5.0) with ssl unset; forwarding a full kwargs dict from a TLS-aware client into a plain connection; mixing the new kwarg into calls that never enable ssl.
Common situations: Client libraries parameterizing every TLS option regardless of scheme; test configs that disable ssl but keep timeout settings; code written against 3.11+ kwargs run through a shared helper used for both TLS and non-TLS targets.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- ssl_handshake_timeout is only meaningful with ssl
- server_hostname is only meaningful with ssl
- You must set server_hostname when using ssl without a host
- host/port and sock can not be specified at the same time
- host and port was not specified and no sock specified
AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17).
Data as JSON: /api/errors/3b324f3facfe2234.
Report an issue: GitHub.