-
Type:
Bug
-
Resolution: Cannot Reproduce
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: TLS/SSL
-
None
-
None
-
Python Drivers
-
None
-
None
-
None
-
None
-
None
-
None
----------------------------------------------------------------------
Summary
Short-lived batch processes intermittently die with SIGSEGV (exit 139) a few seconds after start. In every case where Python's faulthandler captured the faulting thread (3 of 3), it is a PyMongo server Monitor thread opening its connection, inside PyOpenSSL's Connection.do_handshake called from pymongo/pyopenssl_context.py. The stacks are line-for-line identical across four different container builds and across PyMongo 4.18.1 and 4.18.2.
Faulting thread (faulthandler, all_threads=False)
Fatal Python error: Segmentation fault Stack (most recent call first): File ".../OpenSSL/SSL.py", line 2486 in do_handshake File ".../pymongo/pyopenssl_context.py", line 129 in _call File ".../pymongo/pyopenssl_context.py", line 154 in do_handshake File ".../pymongo/pyopenssl_context.py", line 397 in wrap_socket File ".../pymongo/pool_shared.py", line 586 in _configured_socket_interface File ".../pymongo/synchronous/pool.py", line 869 in connect File ".../pymongo/synchronous/pool.py", line 1025 in _get_conn File ".../pymongo/synchronous/pool.py", line 1196 in __enter__ File ".../pymongo/synchronous/monitor.py", line 286 in _check_once File ".../pymongo/synchronous/monitor.py", line 252 in _check_server File ".../pymongo/synchronous/monitor.py", line 205 in _run File ".../pymongo/synchronous/monitor.py", line 70 in target File ".../pymongo/periodic_executor.py", line 237 in _run File ".../threading.py", line 1012 in run File ".../threading.py", line 1075 in _bootstrap_inner File ".../threading.py", line 1032 in _bootstrap
No Python frame from the OCSP client callback appears above do_handshake, so the fault is in native code during SSL_do_handshake rather than inside _ocsp_callback.
Environment
- PyMongo 4.18.2 (also 4.18.1, same stack and line numbers)
- pyOpenSSL 26.4.0, cryptography 50.0.1 (bundled OpenSSL 4.0.2, 25 Aug 2026)
- CPython 3.12.14, Debian trixie base (glibc 2.41), Linux 6.1 x86_64
- AWS ECS Fargate, 1 vCPU / 2 GiB; not memory: the startup sample shows ~17 MB RSS, and ECS reports exit 139, not OutOfMemoryError
- Server: MongoDB Atlas replica set, mongodb+srv://...?retryWrites=true&w=majority&appName=... (TLS via SRV default; no tls* options, OCSP settings left at defaults)
- Client options: maxPoolSize=10, maxIdleTimeMS=60000, serverSelectionTimeoutMS=30000, connectTimeoutMS=10000; each client is pinged (admin.command('ping')) right after construction
- service_identity installed. pyOpenSSL is present only because another library in the process (Scrapy / Twisted 26.4.0) requires it; PyMongo selects it automatically for the sync client (ssl_support.get_ssl_context: is_sync and HAVE_PYSSL).
Pattern
- About 4 crashes in 5 days out of roughly 1,400 process runs (~0.3%). The process does the same startup every run.
- Always 7.6 to 8.8 s after process start, while the application is constructing its MongoClients (one per component, at least four per process, created sequentially). Each crash came within about a second of a new client being created; three came 0.04 to 0.7 s after a client's startup ping returned, one while the process's first client was still coming up.
- Never later in the run, once all clients are up.
- One crash happened before the Twisted reactor had started, so concurrent PyOpenSSL use by the other library does not appear to be required. (Earlier in startup the process makes stdlib-ssl HTTPS calls to AWS APIs; those go through the interpreter's own OpenSSL, not cryptography's bundled copy.)
What we tried
A local control with the exact same container image and the PyOpenSSL backend: 3,200 successful handshakes through PyMongo's pyopenssl_context, 16 concurrent threads sharing one context, against a loopback TLS server. No crash. That control did not use Atlas (real certificate chain, SRV topology, stapled OCSP behind request_ocsp()), so it does not rule those out.
Questions
- Is this a known problem with pyOpenSSL 26.x / cryptography 50 (OpenSSL 4.0) in the pyopenssl_context path, or with concurrent first handshakes from several Monitor threads sharing one SSL_CTX?
- Is there a supported way to make the synchronous client use the stdlib ssl backend when pyOpenSSL is installed for another library's sake?
- Anything we could capture on the next occurrence that would help (we have faulthandler output only; core dumps are not currently enabled)?
----------------------------------------------------------------------
- related to
-
PYTHON-6148 OCSP: a malformed response can crash the TLS handshake instead of soft-failing
-
- Ready for Work
-