The Fix
Upgrade to version 0.7.2 or later.
Based on closed encode/httpx issue #1393 · PR/commit linked
Production note: This tends to surface only under concurrency. Reproduce with load tests and watch for lock contention/cancellation paths.
@@ -98,8 +98,12 @@ def __init__(self) -> None:
), "The 'brotlipy' or 'brotli' library must be installed to use 'BrotliDecoder'"
self.decompressor = brotli.Decompressor()
+ self.seen_data = False
def decode(self, data: bytes) -> bytes:
$ HTTPX_LOG_LEVEL=debug python debug/bug.py
getting result
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
Traceback (most recent call last):
File "/Users/florimond/Developer/python-projects/httpx/debug/bug.py", line 30, in <module>
main()
File "/Users/florimond/Developer/python-projects/httpx/debug/bug.py", line 25, in main
response = future.result()
File "/Users/florimond/.pyenv/versions/3.9.0/lib/python3.9/concurrent/futures/_base.py", line 433, in result
return self.__get_result()
File "/Users/florimond/.pyenv/versions/3.9.0/lib/python3.9/concurrent/futures/_base.py", line 389, in __get_result
raise self._exception
File "/Users/florimond/.pyenv/versions/3.9.0/lib/python3.9/concurrent/futures/thread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File "/Users/florimond/Developer/python-projects/httpx/debug/bug.py", line 13, in do_post
response = client.post("post")
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 992, in post
return self.request(
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 733, in request
return self.send(
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 767, in send
response = self._send_handling_auth(
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 805, in _send_handling_auth
response = self._send_handling_redirects(
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 837, in _send_handling_redirects
response = self._send_single_request(request, timeout)
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 861, in _send_single_request
(status_code, headers, stream, ext) = transport.request(
File "/Users/florimond/Developer/python-projects/httpx/venv/lib/python3.9/site-packages/httpcore/_sync/connection_pool.py", line 200, in request
response = connection.request(
File "/Users/florimond/Developer/python-projects/httpx/venv/lib/python3.9/site-packages/httpcore/_sync/connection.py", line 88, in request
self._create_connection(self.socket)
File "/Users/florimond/Developer/python-projects/httpx/venv/lib/python3.9/site-packages/httpcore/_sync/connection.py", line 136, in _create_connection
from .http11 import SyncHTTP11Connection
ImportError: cannot import name 'SyncHTTP11Connection' from partially initialized module 'httpcore._sync.http11' (most likely due to a circular import) (/Users/florimond/Developer/python-projects/httpx/venv/lib/python3.9/site-packages/httpcore/_sync/http11.py)
Re-run: HTTPX_LOG_LEVEL=debug python debug/bug.py
Option A — Upgrade to fixed release\nUpgrade to version 0.7.2 or later.\nWhen NOT to use: This fix is not applicable if using a different HTTP version or if the application relies on local imports for thread safety.\n\n
Why This Fix Works in Production
- Trigger: $ HTTPX_LOG_LEVEL=debug python debug/bug.py
- Mechanism: Fixed an ImportError related to SyncHTTP11Connection when using ThreadPoolExecutor on Python 3.9 by moving the local import to a global one.
- Why the fix works: Fixed an ImportError related to SyncHTTP11Connection when using ThreadPoolExecutor on Python 3.9 by moving the local import to a global one. (first fixed release: 0.7.2).
- If left unfixed, failures can be intermittent under concurrency (hard to reproduce; shows up as sporadic 5xx/timeouts).
Why This Breaks in Prod
- Shows up under Python 3.9 in real deployments (not just unit tests).
- Surfaces as: $ HTTPX_LOG_LEVEL=debug python debug/bug.py
Proof / Evidence
- GitHub issue: #1393
- Fix PR: https://github.com/encode/httpcore/pull/237
- First fixed release: 0.7.2
- Reproduced locally: No (not executed)
- Last verified: 2026-02-09
- Confidence: 0.85
- Did this fix it?: Yes (upstream fix exists)
- Own content ratio: 0.29
Discussion
High-signal excerpts from the issue thread (symptoms, repros, edge-cases).
“Woah, that's umm, weird”
“Hi @florimondmanca! 1. Yes 2. Yes, with 4 workers; sometimes with 2-3 workers. 3. Not sure, sorry. I am not too familiar with it go…”
“Ah, also a funny bit of info: this only reproduces on http11, not http2. Eg Client(..., http2=True) makes the bug go away. 🤔”
“Yup — moving the local import of SyncHTTP11Connection to a global one (which is fine — we don't need a local import there, since h11…”
Failure Signature (Search String)
- $ HTTPX_LOG_LEVEL=debug python debug/bug.py
Error Message
Stack trace
Error Message
-------------
$ HTTPX_LOG_LEVEL=debug python debug/bug.py
getting result
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
Traceback (most recent call last):
File "/Users/florimond/Developer/python-projects/httpx/debug/bug.py", line 30, in <module>
main()
File "/Users/florimond/Developer/python-projects/httpx/debug/bug.py", line 25, in main
response = future.result()
File "/Users/florimond/.pyenv/versions/3.9.0/lib/python3.9/concurrent/futures/_base.py", line 433, in result
return self._
... (truncated) ...
Minimal Reproduction
$ HTTPX_LOG_LEVEL=debug python debug/bug.py
getting result
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:08] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
DEBUG [2020-11-20 09:30:09] httpx._client - HTTP Request: POST https://httpbin.org/post "HTTP/1.1 200 OK"
Traceback (most recent call last):
File "/Users/florimond/Developer/python-projects/httpx/debug/bug.py", line 30, in <module>
main()
File "/Users/florimond/Developer/python-projects/httpx/debug/bug.py", line 25, in main
response = future.result()
File "/Users/florimond/.pyenv/versions/3.9.0/lib/python3.9/concurrent/futures/_base.py", line 433, in result
return self.__get_result()
File "/Users/florimond/.pyenv/versions/3.9.0/lib/python3.9/concurrent/futures/_base.py", line 389, in __get_result
raise self._exception
File "/Users/florimond/.pyenv/versions/3.9.0/lib/python3.9/concurrent/futures/thread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File "/Users/florimond/Developer/python-projects/httpx/debug/bug.py", line 13, in do_post
response = client.post("post")
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 992, in post
return self.request(
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 733, in request
return self.send(
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 767, in send
response = self._send_handling_auth(
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 805, in _send_handling_auth
response = self._send_handling_redirects(
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 837, in _send_handling_redirects
response = self._send_single_request(request, timeout)
File "/Users/florimond/Developer/python-projects/httpx/httpx/_client.py", line 861, in _send_single_request
(status_code, headers, stream, ext) = transport.request(
File "/Users/florimond/Developer/python-projects/httpx/venv/lib/python3.9/site-packages/httpcore/_sync/connection_pool.py", line 200, in request
response = connection.request(
File "/Users/florimond/Developer/python-projects/httpx/venv/lib/python3.9/site-packages/httpcore/_sync/connection.py", line 88, in request
self._create_connection(self.socket)
File "/Users/florimond/Developer/python-projects/httpx/venv/lib/python3.9/site-packages/httpcore/_sync/connection.py", line 136, in _create_connection
from .http11 import SyncHTTP11Connection
ImportError: cannot import name 'SyncHTTP11Connection' from partially initialized module 'httpcore._sync.http11' (most likely due to a circular import) (/Users/florimond/Developer/python-projects/httpx/venv/lib/python3.9/site-packages/httpcore/_sync/http11.py)
Environment
- Python: 3.9
What Broke
Application crashes intermittently when using ThreadPoolExecutor with multiple workers, causing request failures.
Fix Options (Details)
Option A — Upgrade to fixed release Safe default (recommended)
Upgrade to version 0.7.2 or later.
Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.
Fix reference: https://github.com/encode/httpcore/pull/237
First fixed release: 0.7.2
Last verified: 2026-02-09. Validate in your environment.
When NOT to Use This Fix
- This fix is not applicable if using a different HTTP version or if the application relies on local imports for thread safety.
Verify Fix
Re-run: HTTPX_LOG_LEVEL=debug python debug/bug.py
Did This Fix Work in Your Case?
Quick signal helps us prioritize which fixes to verify and improve.
Prevention
- Add a CI check that diffs key outputs after upgrades (OpenAPI schema snapshots, JSON payload shapes, CLI output).
- Upgrade behind a canary and run integration tests against the canary before 100% rollout.
- Add a TLS smoke test that performs a real handshake in CI (include CA bundle validation and hostname checks).
- Alert on handshake failures by error string and endpoint to catch cert/CA changes quickly.
Version Compatibility Table
| Version | Status |
|---|---|
| 0.7.2 | Fixed |
Related Issues
No related fixes found.
Sources
We don’t republish the full GitHub discussion text. Use the links above for context.