The Fix
pip install urllib3==1.25.9
Based on closed urllib3/urllib3 issue #1746 · PR/commit linked
Production note: Most teams hit this during upgrades or environment changes. Roll out with a canary and smoke critical endpoints (health, OpenAPI/docs) before 100%.
@@ -54,8 +54,7 @@ class Retry(object):
Set to ``None`` to remove this constraint and fall back on other
- counts. It's a good idea to set this to some sensibly-high value to
- account for unexpected edge cases and avoid infinite retry loops.
+ counts.
from urllib3 import PoolManager
from urllib3.util.retry import Retry
from urllib3.util.timeout import Timeout
def main(**kwargs):
url = 'https://78.155.216.172'
mgr = PoolManager()
retry_opts = {
'total': None,
'redirect': 3,
'raise_on_redirect': True,
'connect': 1,
'read': 1,
}
res = mgr.request(
'GET',
url,
retries=Retry(
**retry_opts,
),
timeout=Timeout(
connect=3,
read=5,
),
)
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
Option A — Upgrade to fixed release\npip install urllib3==1.25.9\nWhen NOT to use: This fix should not be used if the retry mechanism needs to be completely disabled.\n\n
Why This Fix Works in Production
- Trigger: timeout=Timeout(
- Mechanism: The Retry class did not account for other error types, leading to infinite retries on certain exceptions
- Why the fix works: Added an 'other' counter to the Retry class for fine-grained retry configuration, addressing issue #1746. (first fixed release: 1.25.9).
- If left unfixed, the same config can fail only in production (env differences), causing startup failures or partial feature outages.
Why This Breaks in Prod
- The Retry class did not account for other error types, leading to infinite retries on certain exceptions
- Production symptom (often without a traceback): from urllib3.util.timeout import Timeout
Proof / Evidence
- GitHub issue: #1746
- Fix PR: https://github.com/urllib3/urllib3/pull/1824
- First fixed release: 1.25.9
- Reproduced locally: No (not executed)
- Last verified: 2026-02-09
- Confidence: 0.95
- Did this fix it?: Yes (upstream fix exists)
- Own content ratio: 0.43
Verified Execution
We executed the runnable minimal repro in a temporary environment and captured exit codes + logs.
- Status: PASS
- Ran: 2026-02-11T16:52:29Z
- Package: urllib3
- Fixed: 1.25.9
- Mode: fixed_only
- Outcome: ok
Logs
Discussion
High-signal excerpts from the issue thread (symptoms, repros, edge-cases).
“@pquentin Docs say "total (int) – Total number of retries to allow”
“Well, anyway it is a bug in design of retrying mechanism because I can't: * set total to low value like 0 or zero *…”
“> Are not these mutually exclusive statements? No, because "other counts" does not include all possible exceptions, while "total" does”
“Well, if you mean this other counter will work for any error not covered by (connect + read + redirect) then, yes, it would work.…”
Failure Signature (Search String)
- timeout=Timeout(
Copy-friendly signature
Failure Signature
-----------------
from urllib3.util.timeout import Timeout
timeout=Timeout(
Error Message
Signature-only (no traceback captured)
Error Message
-------------
from urllib3.util.timeout import Timeout
timeout=Timeout(
Minimal Reproduction
from urllib3 import PoolManager
from urllib3.util.retry import Retry
from urllib3.util.timeout import Timeout
def main(**kwargs):
url = 'https://78.155.216.172'
mgr = PoolManager()
retry_opts = {
'total': None,
'redirect': 3,
'raise_on_redirect': True,
'connect': 1,
'read': 1,
}
res = mgr.request(
'GET',
url,
retries=Retry(
**retry_opts,
),
timeout=Timeout(
connect=3,
read=5,
),
)
What Broke
Retries on SSL errors caused excessive connection attempts, leading to degraded service availability.
Why It Broke
The Retry class did not account for other error types, leading to infinite retries on certain exceptions
Fix Options (Details)
Option A — Upgrade to fixed release Safe default (recommended)
pip install urllib3==1.25.9
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/1824
First fixed release: 1.25.9
Last verified: 2026-02-09. Validate in your environment.
When NOT to Use This Fix
- This fix should not be used if the retry mechanism needs to be completely disabled.
Verify Fix
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.
- 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 |
|---|---|
| 1.25.9 | Fixed |
Related Issues
No related fixes found.
Sources
We don’t republish the full GitHub discussion text. Use the links above for context.