Skip to content
ExplainerBackend

401 vs 403, the difference in one request

401 means the server doesn't know who you are; 403 means it does, and the answer is no. Watch one request hit both gates.

2 min read
401 vs 403, the difference in one request, the opening step of the interactive scene

A request arrives

One request, on its way to a protected resource.

Step 1 of 4

401 and 403 get swapped constantly, and the fix is one question: is the server failing to identify you, or refusing you? Step through the scene above and the two stop blurring together.

Two gates, in order

Every protected request passes two checks. Authentication asks "who are you?" and authorization asks "may you do this?". They run in that order, and each has its own failure code.

  • 401 Unauthorized is the authentication gate. The server cannot tell who you are: no credential, an expired session, an invalid token. Signing in fixes it.
  • 403 Forbidden is the authorization gate. The server knows exactly who you are and the answer is still no. Signing in again changes nothing.

Why the distinction matters

Return the wrong one and you send the reader down the wrong path: a 403 dressed up as a 401 tells a user to log in again forever, and a 401 dressed up as a 403 hides a plain "your session expired".

function requireOwner(req, res, next) {
  if (!req.user) return res.sendStatus(401); // no identity
  if (req.user.id !== req.order.ownerId) return res.sendStatus(403); // not allowed
  next();
}

The status code is the whole message here. The MDN reference on 403 covers the edge cases; the lesson builds the ownership check that decides between the two.

Common questions

If I am logged in, can I still get a 401?
Yes, if your session expired or your token is invalid. 401 is about the credential on this request, not whether you once signed in.
When should a 403 be a 404 instead?
When you do not want to reveal that a resource exists. Returning 404 hides it; 403 openly admits it exists and that you cannot have it.
Which do I return for a missing API key?
401. No key means no identity. Reserve 403 for a valid identity that simply lacks permission.