Handling Authentication Errors
1. Understanding Authentication Error Codes
| Code | Meaning |
|---|---|
| 400 | Malformed request |
| 401 | Missing/invalid credentials |
| 403 | Authenticated but forbidden |
| 429 | Rate limit exceeded |
| 503 | Auth service unavailable |
2. Implementing 401 Unauthorized Responses
Example: WWW-Authenticate
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api",
error="invalid_token",
error_description="The access token expired"
Content-Type: application/problem+json
{"type":"...","title":"Unauthorized","status":401}
3. Using 403 Forbidden Responses
| Use | Detail |
|---|---|
| Authenticated | Identity verified |
| Insufficient permission | Cannot perform action |
| Optional | Return 404 to hide resource existence |
4. Implementing Error Messages
| Practice | Detail |
|---|---|
| User-facing | Friendly + actionable |
| Machine-readable | Stable error codes |
| No internals | Stack traces in logs only |
5. Preventing Information Disclosure
| Anti-pattern | Fix |
|---|---|
| "User not found" | "Invalid email or password" |
| "Wrong password" | "Invalid email or password" |
| Stack trace | Generic 500 to user |
| Version disclosure | Suppress Server header |
6. Using Generic Error Responses
Example: RFC 7807 problem+json
{
"type": "https://app.example/problems/auth-failed",
"title": "Authentication failed",
"status": 401,
"code": "auth.invalid_credentials",
"trace_id": "01HK..."
}
7. Implementing Token Expiration Handling
| Server | Client |
|---|---|
401 + error="invalid_token", error_description="expired" | Trigger silent refresh; retry once |
8. Using Standardized Error Format
| Standard | Detail |
|---|---|
| RFC 7807 | problem+json |
| RFC 6750 | OAuth Bearer error params |
| RFC 9457 | Updated problem details (2023) |
9. Implementing WWW-Authenticate Header
| Param | Detail |
|---|---|
| realm | Protection space |
| error | invalid_request | invalid_token | insufficient_scope |
| error_description | Human-readable |
| scope | Required scopes (for insufficient_scope) |