Authentication Errors
title: "Authentication Errors — Handling Missing and Invalid Credentials" description: "API authentication errors return 401 for missing/invalid credentials and 403 for valid but insufficient permissions, with clear messages about required auth methods." date: 2026-06-28 lastmod: 2026-06-28 weight: 15 tags: [apis, error-handling] }
Authentication errors occur when a client fails to prove their identity, requiring 401 Unauthorized for missing/invalid credentials and 403 Forbidden for insufficient permissions.
What You'll Learn
- Distinguishing 401 from 403 errors
- Common authentication failure patterns
- Secure error messages that don't aid attackers
Why It Matters
Authentication errors are common but sensitive. Too much information helps attackers; too little frustrates legitimate developers.
flowchart TD
A["Client Request"] --> B{"Has Auth?"}
B -->|"No"| C["401 + WWW-Authenticate"]
B -->|"Yes"| D{"Credentials Valid?"}
D -->|"No"| E["401 + Invalid credentials"]
D -->|"Yes"| F{"Has Permission?"}
F -->|"No"| G["403 + Insufficient scope"]
F -->|"Yes"| H["200 OK - Process request"]
style B fill:#dbeafe,stroke:#2563eb
Code Examples
# Authentication error responses
@app.errorhandler(401)
def unauthorized(error):
return jsonify({
"error": "UNAUTHORIZED",
"message": "Authentication required",
"auth_url": "https://docs.example.com/auth"
}), 401, {"WWW-Authenticate": "Bearer"}
@app.errorhandler(403)
def forbidden(error):
return jsonify({
"error": "FORBIDDEN",
"message": "You don't have permission to access this resource",
"required_scope": error.description.get("scope", "admin")
}), 403
// Express auth error middleware
function authError(err, req, res, next) {
if (err.name === 'UnauthorizedError') {
return res.status(401).json({
error: 'UNAUTHORIZED',
message: 'Invalid or expired token',
code: 'TOKEN_EXPIRED'
});
}
if (err.name === 'ForbiddenError') {
return res.status(403).json({
error: 'FORBIDDEN',
message: `Required scope: ${err.requiredScope}`,
required_scope: err.requiredScope
});
}
next(err);
}
Common Mistakes
1. Returning 403 Instead of 401
Use 401 when no/invalid auth; 403 when auth is valid but not enough.
2. Revealing Whether User Exists
"Invalid username" or "Invalid password" separately helps attackers enumerate users.
3. Not Including WWW-Authenticate Header
The WWW-Authenticate header tells clients which auth scheme to use.
4. Expired Token Without Clear Code
Return a specific error code like TOKEN_EXPIRED so clients can refresh.
5. No Auth Documentation in Error Response
Include a link to auth documentation so developers know what to do.
Practice Questions
- What is the difference between 401 and 403?
- Why should you avoid distinguishing "user not found" from "wrong password"?
- What is the purpose of the WWW-Authenticate header?
- How should expired tokens be communicated?
- Why include a link to auth documentation in errors?
Answers:
- 401 means no/invalid credentials; 403 means valid credentials but insufficient permissions.
- Attackers can enumerate valid usernames.
- It tells the client what authentication scheme to use (Bearer, Basic, Digest).
- With a specific error code like
TOKEN_EXPIREDand a refresh endpoint URL. - So developers can quickly find how to authenticate correctly.
Challenge: Design an auth error handling system that returns 401 for expired tokens, 403 for insufficient scopes, and 401 with WWW-Authenticate for missing credentials.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro