ReferenceBeginner3-5 min reference
Auth Error Codes
The most-confused pair in testing is 401 vs 403. This sheet pins down the status codes an authentication/authorization flow should return, what each actually means, and the check behind it. For the full status-code list see the HTTP Status Codes sheet; for the token mechanics see OAuth and JWT (all linked below).
The codes
| Code | Name | Means | Test |
|---|---|---|---|
| 401 | Unauthorized | Not authenticated — no/invalid/expired credentials | Call with no token, bad token, expired token |
| 403 | Forbidden | Authenticated but not allowed — valid identity, wrong permission | Valid token, access another user's / admin-only resource |
| 419 / 440 | Session expired | Vendor-specific session timeout | Idle past timeout, then act |
| 429 | Too Many Requests | Rate/throttle limit hit | Rapid repeated logins |
| 400 | Bad Request | Malformed auth request | Missing grant params, bad body |
| 404 | Not Found | Sometimes used instead of 403 to hide existence | Confirm intended (anti-enumeration) |
401 vs 403 — the rule
- 401 = "I don't know who you are." → re-authenticate (the response should include a
WWW-Authenticateheader). - 403 = "I know who you are, and you can't do this." → re-authenticating won't help.
- A common bug: returning
200with empty data where403is correct — that's an authorization hole, not a UI quirk.
What to test
- Missing token, malformed token, expired token →
401. - Valid token, wrong scope / another user's resource →
403(not200). - After logout/session expiry, a protected call →
401. - Error bodies are safe — no stack traces, tokens, or "user exists" leaks.
Common mistakes
- Treating
401and403as interchangeable. 200+ empty payload instead of403(hides broken authorization).- Login telling attackers "wrong password" vs "no such user" (enumeration).
- Leaking tokens or internal detail in the error response.
// Related resources