From 9c25d4f56cadd4f72dc15b352fcc18d8888b70d4 Mon Sep 17 00:00:00 2001 From: "rodrigo.nogueira" Date: Thu, 15 Jan 2026 12:05:19 -0300 Subject: [PATCH] Improve SSL error message with helpful hints (#3713) --- httpx/_transports/default.py | 2 ++ tests/test_exceptions.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/httpx/_transports/default.py b/httpx/_transports/default.py index fc8c70970a..6fcfbb95c3 100644 --- a/httpx/_transports/default.py +++ b/httpx/_transports/default.py @@ -115,6 +115,8 @@ def map_httpcore_exceptions() -> typing.Iterator[None]: raise message = str(exc) + if "WRONG_VERSION_NUMBER" in message or "RECORD_LAYER_FAILURE" in message: + message += " (Hint: HTTPS to HTTP server, or stale connection pool)" raise mapped_exc(message) from exc diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 60c8721c02..7effd5e251 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -61,3 +61,26 @@ def test_request_attribute() -> None: request = httpx.Request("GET", "https://www.example.com") exc = httpx.ReadTimeout("Read operation timed out", request=request) assert exc.request == request + + +def test_ssl_error_message_enhancement() -> None: + """ + SSL handshake failures should include helpful hints about possible causes. + Regression test for: https://github.com/encode/httpx/issues/3713 + """ + from httpx._transports.default import map_httpcore_exceptions + + ssl_error_messages = [ + "[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1000)", + "[SSL: RECORD_LAYER_FAILURE] record layer failure (_ssl.c:1081)", + ] + + for original_message in ssl_error_messages: + with pytest.raises(httpx.ConnectError) as exc_info: + with map_httpcore_exceptions(): + raise httpcore.ConnectError(original_message) + + enhanced_message = str(exc_info.value) + assert original_message in enhanced_message + assert "Hint:" in enhanced_message + assert "stale connection pool" in enhanced_message