The Fix
pip install fastapi==0.128.5
Based on closed fastapi/fastapi issue #10177 · 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%.
@@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
+# Use Old 403 Authentication Error Status Codes { #use-old-403-authentication-error-status-codes }
+
+Before FastAPI version `0.122.0`, when the integrated security utilities returned an error to the client after a failed authentication, they used the HTTP status code `403 Forbidden`.
invalid_request
The request is missing a required parameter, includes an
unsupported parameter or parameter value, repeats the same
parameter, uses more than one method for including an access
token, or is otherwise malformed. The resource server SHOULD
respond with the HTTP 400 (Bad Request) status code.
invalid_token
The access token provided is expired, revoked, malformed, or
invalid for other reasons. The resource SHOULD respond with
the HTTP 401 (Unauthorized) status code. The client MAY
request a new access token and retry the protected resource
request.
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
Option A — Upgrade to fixed release\npip install fastapi==0.128.5\nWhen NOT to use: Do not use this fix if your application relies on 403 responses for unauthenticated requests.\n\nOption C — Workaround\nlimit the version to `fastapi[all]<0.122.0"` or fix your tests to expect now 401 instead of 403.\nWhen NOT to use: Do not use this fix if your application relies on 403 responses for unauthenticated requests.\n\n
Why This Fix Works in Production
- Trigger: HTTPBearer security scheme enabled as a dependency is returning a `403` when a request is unauthenticated because of a missing or a malformed `authorization`…
- Mechanism: HTTPBearer security scheme incorrectly returns 403 instead of 401 for unauthenticated requests
- Why the fix works: Changes the HTTP status code returned by security classes from 403 to 401 when credentials are missing, aligning with standard practices. (first fixed release: 0.128.5).
- 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
- HTTPBearer security scheme incorrectly returns 403 instead of 401 for unauthenticated requests
- Production symptom (often without a traceback): HTTPBearer security scheme enabled as a dependency is returning a `403` when a request is unauthenticated because of a missing or a malformed `authorization` header. In those scenarios, a `401` should be returned instead.</div>
Proof / Evidence
- GitHub issue: #10177
- Fix PR: https://github.com/fastapi/fastapi/pull/13786
- First fixed release: 0.128.5
- 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.53
Discussion
High-signal excerpts from the issue thread (symptoms, repros, edge-cases).
“This not only affects the HTTPBearer, but a lot of other classes in the security scope also return 403 in "Not authenticated" cases where they…”
“Will there be any progress in the future? Will this error be fixed? I just hope that when the client receives a 403 response, it…”
“For those who are interested in getting this issue resolved, please review #13786”
“Sorry, my misunderstanding. At any rate, I don't think it is necessary after reading section 3 again I realised they offered an example for this…”
Failure Signature (Search String)
- HTTPBearer security scheme enabled as a dependency is returning a `403` when a request is unauthenticated because of a missing or a malformed `authorization` header. In those
- I use the `auto_error=False` and control the correct http error code manually.
Copy-friendly signature
Failure Signature
-----------------
HTTPBearer security scheme enabled as a dependency is returning a `403` when a request is unauthenticated because of a missing or a malformed `authorization` header. In those scenarios, a `401` should be returned instead.</div>
I use the `auto_error=False` and control the correct http error code manually.
Error Message
Signature-only (no traceback captured)
Error Message
-------------
HTTPBearer security scheme enabled as a dependency is returning a `403` when a request is unauthenticated because of a missing or a malformed `authorization` header. In those scenarios, a `401` should be returned instead.</div>
I use the `auto_error=False` and control the correct http error code manually.
Minimal Reproduction
invalid_request
The request is missing a required parameter, includes an
unsupported parameter or parameter value, repeats the same
parameter, uses more than one method for including an access
token, or is otherwise malformed. The resource server SHOULD
respond with the HTTP 400 (Bad Request) status code.
invalid_token
The access token provided is expired, revoked, malformed, or
invalid for other reasons. The resource SHOULD respond with
the HTTP 401 (Unauthorized) status code. The client MAY
request a new access token and retry the protected resource
request.
What Broke
Clients receive 403 Forbidden responses instead of 401 Unauthorized when authentication is missing.
Why It Broke
HTTPBearer security scheme incorrectly returns 403 instead of 401 for unauthenticated requests
Fix Options (Details)
Option A — Upgrade to fixed release Safe default (recommended)
pip install fastapi==0.128.5
Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.
Option C — Workaround Temporary workaround
limit the version to `fastapi[all]<0.122.0"` or fix your tests to expect now 401 instead of 403.
Use only if you cannot change versions today. Treat this as a stopgap and remove once upgraded.
Fix reference: https://github.com/fastapi/fastapi/pull/13786
First fixed release: 0.128.5
Last verified: 2026-02-09. Validate in your environment.
When NOT to Use This Fix
- Do not use this fix if your application relies on 403 responses for unauthenticated requests.
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
- 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.
Version Compatibility Table
| Version | Status |
|---|---|
| 0.128.5 | Fixed |
Related Issues
No related fixes found.
Sources
We don’t republish the full GitHub discussion text. Use the links above for context.