Updated 10 hours ago
The HTTP specification made an unfortunate naming choice. 401 is called "Unauthorized" but actually means unauthenticated—the server doesn't know who you are. 403 "Forbidden" is the real authorization failure—the server knows exactly who you are and has decided you can't do that.
This naming confusion causes more API bugs than almost any other HTTP misunderstanding. Once you see the distinction clearly, you'll never mix them up again.
The Building Security Metaphor
This isn't just an analogy—it's actually how authentication and authorization work:
401 Unauthorized: You're at the door without an ID badge. Security doesn't know who you are. They can't check your clearance level because they don't know your identity. Show your badge first.
403 Forbidden: You have your ID badge. Security knows you're Alice from Engineering. But you're trying to enter the Executive Floor, and Alice from Engineering isn't on the access list. No amount of re-showing your badge will change this.
The guard always checks identity before checking permissions. Authentication precedes authorization. Always.
401: "Who Are You?"
A 401 response means:
- No credentials were provided, OR
- The credentials are invalid (wrong password, malformed token), OR
- The credentials have expired
The solution is always the same: provide valid credentials and try again.
The WWW-Authenticate header is required by the HTTP specification. It tells the client what authentication method to use—Bearer tokens, Basic auth, or something else. Omitting this header is a spec violation.
When to Return 401
No credentials provided:
Invalid credentials:
Expired token:
How Clients Should Respond
When you receive 401: re-authenticate. Refresh the token. Prompt the user to log in again. Then retry the request.
403: "The Answer Is No"
A 403 response means:
- The server knows who you are (authentication succeeded)
- You don't have permission to do this specific thing
- Re-authenticating won't help—this is a policy decision
No WWW-Authenticate header needed. The problem isn't authentication.
When to Return 403
Accessing another user's data:
Missing required role:
Account suspended:
How Clients Should Respond
When you receive 403: don't retry. The problem isn't your credentials—it's your permissions. Show the user an error message. Navigate them somewhere they can actually go.
The Decision
When a request comes in:
- Are credentials present? No → 401
- Are credentials valid? No → 401
- Does this user have permission? No → 403
- Otherwise → Process the request
Authentication happens before authorization. You can't check permissions for someone you haven't identified.
Complete Example
An admin-only endpoint:
Server Implementation
Common Mistakes
Using 401 when you mean 403:
Using 403 when you mean 401:
Forgetting WWW-Authenticate:
Security Consideration: Hiding Resource Existence
Sometimes you want to hide whether a resource exists:
Using 403 for nonexistent resources prevents enumeration attacks but reduces API transparency. Choose based on your security requirements.
Frequently Asked Questions About 401 and 403
Was this page helpful?