aio-libs/aiohttp · critical · RuntimeError
SSL is not supported.
Error message
SSL is not supported.
What it means
Raised by GunicornWebWorker._create_ssl_context() when the Python `ssl` stdlib module failed to import. The import at the top of worker.py is wrapped in try/except ImportError and falls back to ssl=None; if you then enable SSL in the gunicorn config (certfile/keyfile/ssl_version), the worker cannot build an SSLContext and aborts.
Source
Thrown at aiohttp/worker.py:223
self.cfg.worker_int(self)
# wakeup closing process
self._notify_waiter_done()
def handle_abort(self, sig: int, frame: FrameType | None) -> None:
self.alive = False
self.exit_code = 1
self.cfg.worker_abort(self)
sys.exit(1)
@staticmethod
def _create_ssl_context(cfg: Any) -> "SSLContext":
"""Creates SSLContext instance for usage in asyncio.create_server.
See ssl.SSLSocket.__init__ for more details.
"""
if ssl is None: # pragma: no cover
raise RuntimeError("SSL is not supported.")
ctx = ssl.SSLContext(cfg.ssl_version)
ctx.load_cert_chain(cfg.certfile, cfg.keyfile)
ctx.verify_mode = cfg.cert_reqs
if cfg.ca_certs:
ctx.load_verify_locations(cfg.ca_certs)
if cfg.ciphers:
ctx.set_ciphers(cfg.ciphers)
return ctx
def _get_valid_log_format(self, source_format: str) -> str:
if source_format == self.DEFAULT_GUNICORN_LOG_FORMAT:
return self.DEFAULT_AIOHTTP_LOG_FORMAT
elif re.search(r"%\([^\)]+\)", source_format):
raise ValueError(
"Gunicorn's style options in form of `%(name)s` are not "
"supported for the log formatting. Please use aiohttp's "
"format specification to configure access log formatting: "View on GitHub (pinned to c0ef574e29)
Solutions
- Use a Python build with SSL support: install openssl dev headers and rebuild/reinstall Python, or use an official CPython distribution.
- On Alpine install `libssl`/`libcrypto` and `openssl`; on Debian `apt-get install libssl-dev` and rebuild Python.
- If SSL is not actually required, disable it in the gunicorn config (remove certfile/keyfile) and terminate TLS at a reverse proxy instead.
- Verify with `python -c "import ssl; print(ssl.OPENSSL_VERSION)"` before starting the worker.
Example fix
# verify ssl support first # python -c 'import ssl; print(ssl.OPENSSL_VERSION)' # if it fails, rebuild python with openssl, e.g. on debian: # apt-get install -y libssl-dev && reinstall/rebuild python # gunicorn config: only enable ssl when import ssl works
Defensive patterns
Strategy: validation
Validate before calling
import ssl
def assert_ssl_available():
if ssl is None:
raise RuntimeError("SSL is not supported by this interpreter")
return ssl Type guard
import sys
def has_ssl() -> bool:
try:
import ssl
return True
except ImportError:
return False Prevention
- Run `python -c "import ssl"` before enabling SSL in the gunicorn config.
- Use a Python build linked against OpenSSL (official builds, or install libssl-dev before building).
- Terminate TLS at a reverse proxy if the interpreter cannot support ssl.
When it happens
Trigger: Running the gunicorn aiohttp worker with SSL enabled (`--certfile`/`--keyfile` or `cfg.is_ssl`) on a Python interpreter compiled without OpenSSL/ssl support, so `import ssl` raised ImportError and ssl is None.
Common situations: A custom or minimal Python build (e.g. some embedded/Alpine images without openssl-dev at compile time); a broken system OpenSSL that prevented the ssl module from building; a container image missing libssl.
Related errors
- wsgi app should be either Application or async function retu
- Gunicorn's style options in form of `%(name)s` are not suppo
- ssl should be SSLContext, Fingerprint, or bool, got {ssl!r}
- fingerprint has invalid length
- md5 and sha1 are insecure and not supported. Use sha256.
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/4f3363f1a535bf97.json.
Report an issue: GitHub.