Jump to solution
Verify

The Fix

pip install requests==2.27.0

Based on closed psf/requests issue #1572 · PR/commit linked

Production note: Watch p95/p99 latency and retry volume; timeouts can turn into retry storms and duplicate side-effects.

Jump to Verify Open PR/Commit
@@ -19,6 +19,7 @@ prepend_scheme_if_needed, get_auth_from_url, urldefragauth) from .structures import CaseInsensitiveDict +from .packages.urllib3.exceptions import ClosedPoolError from .packages.urllib3.exceptions import ConnectTimeoutError from .packages.urllib3.exceptions import HTTPError as _HTTPError
repro.py
...... File "C:\Python27\lib\site-packages\requests\sessions.py", line 347, in get return self.request('GET', url, **kwargs) File "C:\Python27\lib\site-packages\requests\sessions.py", line 335, in request resp = self.send(prep, **send_kwargs) File "C:\Python27\lib\site-packages\requests\sessions.py", line 438, in send r = adapter.send(request, **kwargs) File "C:\Python27\lib\site-packages\requests\adapters.py", line 292, in send timeout=timeout File "C:\Python27\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 423, in url open conn = self._get_conn(timeout=pool_timeout) File "C:\Python27\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 224, in _ge t_conn raise ClosedPoolError(self, "Pool is closed.") ClosedPoolError: HTTPConnectionPool(host='......', port=80): Pool is closed.
verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
fix.md
Option A — Upgrade to fixed release\npip install requests==2.27.0\nWhen NOT to use: This fix should not be applied if the application relies on raw urllib3 exceptions.\n\n

Why This Fix Works in Production

  • Mechanism: ClosedPoolError from urllib3 was not being caught and wrapped in requests
  • Why the fix works: Catches and wraps the ClosedPoolError exception from urllib3, preventing it from leaking through the requests API. (first fixed release: 2.27.0).
Production impact:
  • If left unfixed, this can cause silent data inconsistencies that propagate (bad cache entries, incorrect downstream decisions).

Why This Breaks in Prod

  • Shows up under Python 2.7 in real deployments (not just unit tests).
  • ClosedPoolError from urllib3 was not being caught and wrapped in requests
  • Surfaces as: ......

Proof / Evidence

  • GitHub issue: #1572
  • Fix PR: https://github.com/psf/requests/pull/2674
  • First fixed release: 2.27.0
  • Reproduced locally: No (not executed)
  • Last verified: 2026-02-07
  • Confidence: 0.85
  • Did this fix it?: Yes (upstream fix exists)
  • Own content ratio: 0.21

Discussion

High-signal excerpts from the issue thread (symptoms, repros, edge-cases).

“I also got urllib3 exceptions passing through when use Session in several threads, trace:”
@zbb42 · 2013-09-06 · source
“I definitely agree with you and would agree that these should be wrapped. Could you give us stack-traces so we can find where they're bleeding…”
@sigmavirus24 · 2013-09-03 · source
“Sorry I don't have stack traces readily available :/”
@sylvinus · 2013-09-03 · source
“No worries”
@sigmavirus24 · 2013-09-03 · source

Error Message

Stack trace
error.txt
Error Message ------------- ...... File "C:\Python27\lib\site-packages\requests\sessions.py", line 347, in get return self.request('GET', url, **kwargs) File "C:\Python27\lib\site-packages\requests\sessions.py", line 335, in request resp = self.send(prep, **send_kwargs) File "C:\Python27\lib\site-packages\requests\sessions.py", line 438, in send r = adapter.send(request, **kwargs) File "C:\Python27\lib\site-packages\requests\adapters.py", line 292, in send timeout=timeout File "C:\Python27\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 423, in url open conn = self._get_conn(timeout=pool_timeout) File "C:\Python27\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 224, in _ge t_conn raise ClosedPoolError(self, "Pool is closed.") ClosedPoolError: HTTPConnectionPool(host='......', port=80): Pool is closed.
Stack trace
error.txt
Error Message ------------- Traceback (most recent call last): File "/home/krat/Projects/Grubhub/source/Pit/pit/web.py", line 52, in request response = session.request(method, url, **kw) File "/home/krat/.virtualenvs/grubhub/local/lib/python2.7/site-packages/requests/sessions.py", line 357, in request resp = self.send(prep, **send_kwargs) File "/home/krat/.virtualenvs/grubhub/local/lib/python2.7/site-packages/requests/sessions.py", line 460, in send r = adapter.send(request, **kwargs) File "/home/krat/.virtualenvs/grubhub/local/lib/python2.7/site-packages/requests/adapters.py", line 367, in send r.content File "/home/krat/.virtualenvs/grubhub/local/lib/python2.7/site-packages/requests/models.py", line 633, in content self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes() File "/home/krat/.virtualenvs/grubhub/local/lib/python2.7/site-packages/requests/models.py", line 572, in generate decode_content=True): File "/home/krat/.virtualenvs/grubhub/local/lib/python2.7/site-packages/requests/packages/urllib3/response.py", line 225, in stream data = self.read(amt=amt, decode_content=decode_content) File "/home/krat/.virtualenvs/grubhub/local/lib/python2.7/site-packages/requests/packages/urllib3/response.py", line 193, in read e) DecodeError: ('Received response with content-encoding: gzip, but failed to decode it.', error('Error -3 while deco ... (truncated) ...
Stack trace
error.txt
Error Message ------------- Traceback (most recent call last): File "/home/oliver/wc/trunk/mtmCore/python/asagent/samplers/net/web.py", line 255, in process_url resp = self.request(self.params.httpverb, url, data=data) File "/home/oliver/wc/trunk/mtmCore/python/asagent/samplers/net/web.py", line 320, in request verb, url, data=data)) File "abilisoft/requests/opt/abilisoft.com/thirdparty/requests/lib/python2.7/site-packages/requests/sessions.py", line 286, in prepare_request File "abilisoft/requests/opt/abilisoft.com/thirdparty/requests/lib/python2.7/site-packages/requests/models.py", line 286, in prepare File "abilisoft/requests/opt/abilisoft.com/thirdparty/requests/lib/python2.7/site-packages/requests/models.py", line 333, in prepare_url File "abilisoft/requests/opt/abilisoft.com/thirdparty/requests/lib/python2.7/site-packages/requests/packages/urllib3/util.py", line 397, in parse_url LocationParseError: Failed to parse: Failed to parse: fe80::5054:ff:fe5a:fc0

Minimal Reproduction

repro.py
...... File "C:\Python27\lib\site-packages\requests\sessions.py", line 347, in get return self.request('GET', url, **kwargs) File "C:\Python27\lib\site-packages\requests\sessions.py", line 335, in request resp = self.send(prep, **send_kwargs) File "C:\Python27\lib\site-packages\requests\sessions.py", line 438, in send r = adapter.send(request, **kwargs) File "C:\Python27\lib\site-packages\requests\adapters.py", line 292, in send timeout=timeout File "C:\Python27\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 423, in url open conn = self._get_conn(timeout=pool_timeout) File "C:\Python27\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 224, in _ge t_conn raise ClosedPoolError(self, "Pool is closed.") ClosedPoolError: HTTPConnectionPool(host='......', port=80): Pool is closed.

Environment

  • Python: 2.7

What Broke

Users experienced unhandled urllib3 exceptions causing application crashes.

Why It Broke

ClosedPoolError from urllib3 was not being caught and wrapped in requests

Fix Options (Details)

Option A — Upgrade to fixed release Safe default (recommended)

pip install requests==2.27.0

When NOT to use: This fix should not be applied if the application relies on raw urllib3 exceptions.

Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.

Fix reference: https://github.com/psf/requests/pull/2674

First fixed release: 2.27.0

Last verified: 2026-02-07. Validate in your environment.

Get updates

We publish verified fixes weekly. No spam.

Subscribe

When NOT to Use This Fix

  • This fix should not be applied if the application relies on raw urllib3 exceptions.

Verify Fix

verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.

Did This Fix Work in Your Case?

Quick signal helps us prioritize which fixes to verify and improve.

Prevention

  • Track RSS + object counts after deployments; alert on monotonic growth and GC pressure.
  • Add a long-running test that repeats the failing call path and asserts stable memory.
  • Make timeouts explicit and test them (unit + integration) to avoid silent behavior changes.
  • Instrument retries (attempt count + reason) and alert on spikes to catch dependency slowdowns.

Version Compatibility Table

VersionStatus
2.27.0 Fixed

Related Issues

No related fixes found.

Sources

We don’t republish the full GitHub discussion text. Use the links above for context.