Jump to solution
Details

The Fix

pip install requests==2.27.0

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

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

Open PR/Commit
@@ -111,9 +111,11 @@ def resolve_redirects(self, resp, req, stream=False, timeout=None, # Facilitate non-RFC2616-compliant 'location' headers # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') + # Compliant with RFC3986, we percent encode the url. if not urlparse(url).netloc: - # Compliant with RFC3986, we percent encode the url.
fix.md
Option A — Upgrade to fixed release\npip install requests==2.27.0\nWhen NOT to use: Do not use this fix if the server correctly follows RFC 2616.\n\n

Why This Fix Works in Production

  • Trigger: Problem with 301-redirect
  • Mechanism: The remote server is not following RFC 2616, causing issues with location headers
  • Why the fix works: Ensures that location headers are always percent-encoded to handle non-compliant servers, resolving the issue with 301 redirects. (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 3.3 in real deployments (not just unit tests).
  • The remote server is not following RFC 2616, causing issues with location headers
  • Surfaces as: Traceback (most recent call last):\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 428, in urlopen\n…

Proof / Evidence

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

Discussion

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

“Uh...can I ask you to uninstall and reinstall Requests? The TypeError that got thrown should have been impossible to hit, because it's inside a Try/Catch…”
@Lukasa · 2013-05-16 · source
“Ignore the first trace (I'll delete it), the key of the problem is:”
@Cosmologist · 2013-05-16 · source
“Ah, ok, got it”
@Lukasa · 2013-05-16 · source
“Lucasa, thank you very much - now works fine”
@Cosmologist · 2013-05-16 · source

Failure Signature (Search String)

  • Problem with 301-redirect

Error Message

Stack trace
error.txt
Error Message ------------- Traceback (most recent call last):\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 428, in urlopen\n body=body, headers=headers)\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 290, in _make_request\n httplib_response = conn.getresponse()\n File "c:\Python33\lib\http\client.py", line 1143, in getresponse\n response.begin()\n File "c:\Python33\lib\http\client.py", line 354, in begin\n version, status, reason = self._read_status()\n File "c:\Python33\lib\http\client.py", line 324, in _read_status\n raise BadStatusLine(line)
Stack trace
error.txt
Error Message ------------- Traceback (most recent call last):\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\adapters.py", line 283, in send\n timeout=timeout\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 474, in urlopen\n raise MaxRetryError(self, url, e)
Stack trace
error.txt
Error Message ------------- Traceback (most recent call last):\n File "C:/Dropbox/projects/InfoStreams/test.py", line 25, in <module>\n allow_redirects=True)\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\api.py", line 55, in get\n return request('get', url, **kwargs)\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\api.py", line 44, in request\n return session.request(method=method, url=url, **kwargs)\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\sessions.py", line 345, in request\n resp = self.send(prep, **send_kwargs)\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\sessions.py", line 464, in send\n history = [resp for resp in gen] if allow_redirects else []\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\sessions.py", line 464, in <listcomp>\n history = [resp for resp in gen] if allow_redirects else []\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\sessions.py", line 154, in resolve_redirects\n allow_redirects=False,\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\sessions.py", line 448, in send\n r = adapter.send(request, **kwargs)\n File "C:\Dropbox\projects\Helpers\ph\.envwin32\lib\site-packages\requests\adapters.py", line 318, in send\n raise ConnectionError(e)

Environment

  • Python: 3.3

What Broke

Requests fail with MaxRetryError when handling 301 redirects from non-compliant servers.

Why It Broke

The remote server is not following RFC 2616, causing issues with location headers

Fix Options (Details)

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

pip install requests==2.27.0

When NOT to use: Do not use this fix if the server correctly follows RFC 2616.

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

Option D — Guard side-effects with OnceOnly Guardrail for side-effects

Mitigate duplicate external side-effects under retries/timeouts/agent loops by gating the operation before calling external systems.

  • Place OnceOnly between your code/agent and real side-effects (Stripe, emails, CRM, APIs).
  • Use a stable key per side-effect (e.g., customer_id + action + idempotency_key).
  • Fail-safe: configure fail-open vs fail-closed based on blast radius and spend risk.
  • This does NOT fix data corruption; it only prevents duplicate side-effects.
Show example snippet (optional)
onceonly.py
from onceonly import OnceOnly import os once = OnceOnly(api_key=os.environ["ONCEONLY_API_KEY"], fail_open=True) # Stable idempotency key per real side-effect. # Use a request id / job id / webhook delivery id / Stripe event id, etc. event_id = "evt_..." # replace key = f"stripe:webhook:{event_id}" res = once.check_lock(key=key, ttl=3600) if res.duplicate: return {"status": "already_processed"} # Safe to execute the side-effect exactly once. handle_event(event_id)

See OnceOnly SDK

When NOT to use: Do not use this to hide logic bugs or data corruption. Use it to block duplicate external side-effects and enforce tool permissions/spend caps.

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

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

  • Do not use this fix if the server correctly follows RFC 2616.
  • Do not use this to hide logic bugs or data corruption. Use it to block duplicate external side-effects and enforce tool permissions/spend caps.

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.