Jump to solution
Verify

The Fix

Improves the ProxyHeadersMiddleware to correctly handle client addresses from trusted proxies, addressing the issue where clients were reported as [None, 0].

Based on closed Kludex/uvicorn issue #1068 · PR/commit linked

Jump to Verify Open PR/Commit
@@ -93,10 +93,12 @@ Options: --date-header / --no-date-header Enable/Disable default Date header. - --forwarded-allow-ips TEXT Comma separated list of IPs to trust with - proxy headers. Defaults to the - $FORWARDED_ALLOW_IPS environment variable if
repro.py
# app.py from tests.response import Response from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware async def inner(scope, receive, send): scheme = scope["scheme"] host, port = scope["client"] addr = "%s://%s:%d" % (scheme, host, port) response = Response("Remote: " + addr, media_type="text/plain") await response(scope, receive, send) app = ProxyHeadersMiddleware(inner, trusted_hosts=['127.0.0.1'])
verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
fix.md
Option A — Apply the official fix\nImproves the ProxyHeadersMiddleware to correctly handle client addresses from trusted proxies, addressing the issue where clients were reported as [None, 0].\nWhen NOT to use: Do not use this fix if the application is not behind a trusted proxy.\n\n

Why This Fix Works in Production

  • Trigger: E AssertionError: assert 'Remote: https://None:0' == 'Remote: https://1.2.3.4:0'
  • Mechanism: ProxyHeadersMiddleware fails to correctly handle client addresses from trusted proxies
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.9.1 in real deployments (not just unit tests).
  • ProxyHeadersMiddleware fails to correctly handle client addresses from trusted proxies
  • Surfaces as: assert response.text == response_text

Proof / Evidence

Discussion

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

“Hi @jchristgit , yeah send us a repro, in that case the trusted host param you are passing and the headers received should be good…”
@euri10 · 2021-06-02 · repro detail · source
“> I will add a few tests and will try to fix implementation, but the Iack of ready implementations on Github confuses me. Maybe someone…”
@euri10 · 2021-06-07 · source
“could do that, this works but not certain of the edge case or implications”
@euri10 · 2021-06-03 · source
“In my case i use cloudflare.com and it proxy the requests by its Global CDNs when i get a request on uvicorn it shows to…”
@AYMENJD · 2021-06-23 · source

Failure Signature (Search String)

  • E AssertionError: assert 'Remote: https://None:0' == 'Remote: https://1.2.3.4:0'

Error Message

Stack trace
error.txt
Error Message ------------- assert response.text == response_text E AssertionError: assert 'Remote: https://None:0' == 'Remote: https://1.2.3.4:0' E - Remote: https://1.2.3.4:0 E ? ^^^^^^^ E + Remote: https://None:0 E ? ^^^^

Minimal Reproduction

repro.py
# app.py from tests.response import Response from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware async def inner(scope, receive, send): scheme = scope["scheme"] host, port = scope["client"] addr = "%s://%s:%d" % (scheme, host, port) response = Response("Remote: " + addr, media_type="text/plain") await response(scope, receive, send) app = ProxyHeadersMiddleware(inner, trusted_hosts=['127.0.0.1'])

Environment

  • Python: 3.9.1

What Broke

Clients are reported as [None, 0] instead of their actual addresses, causing incorrect client identification.

Why It Broke

ProxyHeadersMiddleware fails to correctly handle client addresses from trusted proxies

Fix Options (Details)

Option A — Apply the official fix

Improves the ProxyHeadersMiddleware to correctly handle client addresses from trusted proxies, addressing the issue where clients were reported as [None, 0].

When NOT to use: Do not use this fix if the application is not behind a trusted proxy.

Fix reference: https://github.com/kludex/uvicorn/pull/2468

Last verified: 2026-02-11. 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 application is not behind a trusted proxy.

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

  • Capture the exact failing error string in logs and tests so you can reproduce via a minimal script.
  • Pin production dependencies and upgrade only with a reproducible test that hits the failing path.

Related Issues

No related fixes found.

Sources

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