RustPython/RustPython · error · RuntimeError

Python ssl module is not available

Error message

Python ssl module is not available

What it means

RuntimeError from BaseEventLoop.start_tls: asyncio's module-level `import ssl` failed, so ssl is None and no TLS upgrade is possible. This is an interpreter/build-level problem — the ssl module itself is missing or unimportable (not built with OpenSSL, restricted embedder, or an interpreter like RustPython where the native ssl module is unavailable).

Source

Thrown at Lib/asyncio/base_events.py:1324

                await proto.drain()
                total_sent += read
        finally:
            if total_sent > 0 and hasattr(file, 'seek'):
                file.seek(offset + total_sent)
            await proto.restore()

    async def start_tls(self, transport, protocol, sslcontext, *,
                        server_side=False,
                        server_hostname=None,
                        ssl_handshake_timeout=None,
                        ssl_shutdown_timeout=None):
        """Upgrade transport to TLS.

        Return a new transport that *protocol* should start using
        immediately.
        """
        if ssl is None:
            raise RuntimeError('Python ssl module is not available')

        if not isinstance(sslcontext, ssl.SSLContext):
            raise TypeError(
                f'sslcontext is expected to be an instance of ssl.SSLContext, '
                f'got {sslcontext!r}')

        if not getattr(transport, '_start_tls_compatible', False):
            raise TypeError(
                f'transport {transport!r} is not supported by start_tls()')

        waiter = self.create_future()
        ssl_protocol = sslproto.SSLProtocol(
            self, protocol, sslcontext, waiter,
            server_side, server_hostname,
            ssl_handshake_timeout=ssl_handshake_timeout,
            ssl_shutdown_timeout=ssl_shutdown_timeout,
            call_connection_made=False)

View on GitHub (pinned to aaeab4f754)

Solutions

  1. Probe support before use: try: import ssl except ImportError: tls_enabled = False, and skip start_tls
  2. On CPython, rebuild/reinstall Python with OpenSSL available (python -c 'import ssl' must succeed)
  3. On embedded builds, register a native ssl module or route TLS through an external proxy/terminator

Example fix

# before
new_tr = await loop.start_tls(transport, protocol, ctx)

# after
try:
    import ssl  # noqa: F401
    tls_ok = True
except ImportError:
    tls_ok = False

if tls_ok:
    new_tr = await loop.start_tls(transport, protocol, ctx)
else:
    raise RuntimeError('TLS unavailable in this build; use a TLS terminator')
Defensive patterns

Strategy: validation

Validate before calling

try:
    import ssl
    TLS_AVAILABLE = True
except ImportError:
    TLS_AVAILABLE = False

if not TLS_AVAILABLE:
    raise RuntimeError('ssl module unavailable; cannot start_tls')
new_tr = await loop.start_tls(transport, protocol, ctx)

Type guard

def tls_supported() -> bool:
    try:
        import ssl  # noqa: F401
        return True
    except ImportError:
        return False

Try / catch

try:
    new_tr = await loop.start_tls(transport, protocol, ctx)
except RuntimeError as e:
    if 'ssl module is not available' in str(e):
        log.error('interpreter built without ssl; route TLS via terminator')
    raise

Prevention

When it happens

Trigger: await loop.start_tls(transport, protocol, ctx) on an interpreter built without ssl support; embedders who did not register the ssl module; RustPython builds where _ssl is not compiled; broken OpenSSL installs making `import ssl` raise at interpreter startup.

Common situations: Embedded Python in a Rust/C application without TLS extensions; minimal or musl-based container images lacking OpenSSL; custom interpreter builds (RustPython, PyPy variants) without _ssl; CI matrices where one runner lacks the ssl build.

Understand the failure class

Related errors


AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17). Data as JSON: /api/errors/831a2cccb5fdb143. Report an issue: GitHub.