Jump to solution
Verify

The Fix

pip install urllib3==2.0.3

Based on closed urllib3/urllib3 issue #3049 · PR/commit linked

Jump to Verify Open PR/Commit
@@ -8,7 +8,7 @@ import typing import zlib -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from http.client import responses
repro.py
import asyncio import sys from tornado import httpserver, ioloop, web from dummyserver.server import run_loop_in_thread, run_tornado_app from dummyserver.proxy import ProxyHandler from dummyserver.handlers import TestingApp from urllib3.poolmanager import ProxyManager, proxy_from_url def main(): with run_loop_in_thread() as io_loop: async def run_app(): app = web.Application([(r".*", TestingApp)]) http_server, http_port = run_tornado_app(app, None, "http", "localhost") proxy_app = web.Application([(r".*", ProxyHandler)]) proxy_server, proxy_port = run_tornado_app( proxy_app, None, "http", "localhost" ) return http_port, proxy_port http_port, proxy_port = asyncio.run_coroutine_threadsafe( run_app(), io_loop.asyncio_loop ).result() http_url = f"http://localhost:{http_port}" proxy_url = f"http://localhost:{proxy_port}" with proxy_from_url(proxy_url) as http: r = http.request( "GET", f"{http_url}/redirect", fields={"target": f"{http_url}/"}, redirect=False, ) breakpoint() assert r.status == 303, f"status was {r.status}" sys.exit(main())
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 urllib3==2.0.3\nWhen NOT to use: Do not use if it changes public behavior or if the failure cannot be reproduced.\n\n

Why This Fix Works in Production

  • Trigger: AssertionError: assert 500 == 303
  • Mechanism: Addresses issues related to Python 3.12.0b1 by ignoring warnings and fixing related bugs, resolving issue #3049.
  • Why the fix works: Addresses issues related to Python 3.12.0b1 by ignoring warnings and fixing related bugs, resolving issue #3049. (first fixed release: 2.0.3).

Why This Breaks in Prod

  • Shows up under Python 3.12 in real deployments (not just unit tests).
  • Surfaces as: Traceback (most recent call last):

Proof / Evidence

  • GitHub issue: #3049
  • Fix PR: https://github.com/urllib3/urllib3/pull/3052
  • First fixed release: 2.0.3
  • 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.25

Discussion

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

“Mmm... The tests passed locally. Cannot reproduce, this is up to a bad start. Ubuntu 22.04 lts.”
@Ousret · 2023-05-30 · source
“I can reproduce the test/with_dummyserver/test_proxy_poolmanager.py::TestHTTPProxyManager::test_redirect failure locally I suspect this is a Python 3.12 bug”
@graingert · 2023-05-30 · source
“It seems the failure is quite brittle, when running the proxy server directly without pytest it works correctly:”
@graingert · 2023-05-30 · source
“Interesting... we both tried and got a different result from the exact Python beta. Could you share the difference? _e.g. what makes it (the proxy)…”
@Ousret · 2023-05-31 · source

Failure Signature (Search String)

  • AssertionError: assert 500 == 303

Error Message

Stack trace
error.txt
Error Message ------------- Traceback (most recent call last): File "/home/runner/work/urllib3/urllib3/test/with_dummyserver/test_proxy_poolmanager.py", line 222, in test_redirect assert r.status == 303 AssertionError: assert 500 == 303 + where 500 = <urllib3.response.HTTPResponse object at 0x7f9a271f3d30>.status
Stack trace
error.txt
Error Message ------------- graingert@conscientious  ~/projects/urllib3   py3-12-debug ± ./.nox/test-3-12/bin/coverage run -m demo Traceback (most recent call last): File "/home/graingert/projects/urllib3/demo.py", line 15, in <module> asyncio.run(main()) File "/usr/lib/python3.12/asyncio/runners.py", line 194, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/asyncio/base_events.py", line 664, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "/home/graingert/projects/urllib3/demo.py", line 13, in main await inner() Exception ✘ graingert@conscientious  ~/projects/urllib3   py3-12-debug ± vim demo.py graingert@conscientious  ~/projects/urllib3   py3-12-debug ± ./.nox/test-3-12/bin/python -m demo good

Minimal Reproduction

repro.py
import asyncio import sys from tornado import httpserver, ioloop, web from dummyserver.server import run_loop_in_thread, run_tornado_app from dummyserver.proxy import ProxyHandler from dummyserver.handlers import TestingApp from urllib3.poolmanager import ProxyManager, proxy_from_url def main(): with run_loop_in_thread() as io_loop: async def run_app(): app = web.Application([(r".*", TestingApp)]) http_server, http_port = run_tornado_app(app, None, "http", "localhost") proxy_app = web.Application([(r".*", ProxyHandler)]) proxy_server, proxy_port = run_tornado_app( proxy_app, None, "http", "localhost" ) return http_port, proxy_port http_port, proxy_port = asyncio.run_coroutine_threadsafe( run_app(), io_loop.asyncio_loop ).result() http_url = f"http://localhost:{http_port}" proxy_url = f"http://localhost:{proxy_port}" with proxy_from_url(proxy_url) as http: r = http.request( "GET", f"{http_url}/redirect", fields={"target": f"{http_url}/"}, redirect=False, ) breakpoint() assert r.status == 303, f"status was {r.status}" sys.exit(main())

Environment

  • Python: 3.12

What Broke

Tests fail with 500 status instead of expected 303, impacting CI/CD pipelines.

Fix Options (Details)

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

pip install urllib3==2.0.3

When NOT to use: Do not use if it changes public behavior or if the failure cannot be reproduced.

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

Fix reference: https://github.com/urllib3/urllib3/pull/3052

First fixed release: 2.0.3

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

Get updates

We publish verified fixes weekly. No spam.

Subscribe

When NOT to Use This Fix

  • Do not use if it changes public behavior or if the failure cannot be reproduced.

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

  • 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.

Version Compatibility Table

VersionStatus
2.0.3 Fixed

Related Issues

No related fixes found.

Sources

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