Skip to main content
APIs6 min readPublished September 19, 2026Updated September 22, 2026

401 vs 403 vs 404 vs 429 vs 500

401 means the server does not know who you are. 403 means it knows and says no. 404 means the thing is not there. 429 means you asked too often. 500 means the server broke while handling a request it accepted. The first four are about your request; the last one is about their code, or yours.

What does each code mean in one line?

CodeMeaningFirst thing to check
401 UnauthorizedNo valid credential was presentedWas an Authorization header sent at all?
403 ForbiddenCredential is valid, action is not permittedPermissions, scopes, row access rules
404 Not FoundNo resource at that pathSpelling of the URL, and whether the record exists
429 Too Many RequestsRate or quota limit hitRetry-After header, and whether code is looping
500 Server ErrorUnhandled failure on the serverServer logs — the browser cannot tell you why

Why is 401 versus 403 the pair that confuses people?

Both read as 'access denied' in the UI, but they point at opposite fixes. 401 is an identity problem: the token is missing, expired, or malformed, and no amount of permission tinkering will help. 403 is a permission problem: identity worked perfectly, and the rules decided this particular action is not allowed.

A practical test: sign out and repeat the request. If the code stays the same, it was never about your account.

Some services deliberately return 404 instead of 403 so strangers cannot discover which records exist. If a 404 appears for something you know is there, consider that you are simply not allowed to see it.

When is 429 your own fault?

More often than people expect. A React effect with the wrong dependency can fire a request on every render; a retry with no delay can turn one failure into fifty. Before assuming the provider is stingy, count the requests in the Network tab over ten seconds.

  • Honour the Retry-After header when the service sends one.
  • Back off exponentially rather than retrying immediately.
  • Cache responses that do not change per request.
  • Move repeated identical calls to the server so one result serves many visitors.

What should you do with a 500?

Stop reading the browser. A 500 means the server accepted the request and then failed; the useful information is in the server log, which usually contains a stack trace naming the exact line. If the 500 comes from your own endpoint, this is a bug you can fix. If it comes from a third party, check their status page before rewriting anything.

Frequently asked questions

Is 400 different from 422?
Both mean the request was rejected as invalid. 400 is the generic version; 422 usually means the shape was understood but the values failed validation.
Why do I get 200 with an error inside?
Some providers always return 200 and put a success flag in the body. Always check that flag as well as the status code.
Which of these can a user cause?
401 and 429 routinely, 403 when they try something not meant for them, 404 by editing a URL. A 500 is nearly always yours.

Practice this in MessyDev

Reading it once helps. Doing it once sticks. These are the hands-on parts of MessyDev that cover the same ground.

Keep going