401 Unauthorized

Authentication is required and has failed or not been provided - despite the name, this means unauthenticated.

What 401 means

401 is misnamed. It means unauthenticated: the request carried no credentials, or the credentials it carried were invalid or expired. The client's correct response is to authenticate and try again.

The specification requires a WWW-Authenticate header on a 401, telling the client which authentication scheme to use. This is very often omitted, which leaves the client without the one piece of information the status code exists to convey.

The distinction from 403 matters operationally, not just pedantically. Client libraries and SDKs typically respond to a 401 by refreshing a token and retrying. If you return 401 for a permissions failure, you send clients into a refresh loop that cannot possibly help - they get a fresh, valid token and are still refused.

There is one deliberate exception: some APIs return 401 rather than 403 or 404 for resources the caller may not know exist, to avoid revealing which resources are present. That is a considered trade-off, not an accident.

Common causes of a 401

  • No Authorization header sent at all.
  • An expired access token - check the exp claim if it is a JWT.
  • A malformed Authorization header: a missing 'Bearer ' prefix, or the token wrapped in quotes.
  • A token signed by a different issuer, or with a key that has since rotated.
  • The token's audience does not match the API being called.
  • A proxy or load balancer stripping the Authorization header before it reaches the application.

How to fix a 401

  • Decode the token and check exp against the current time in seconds, not milliseconds.
  • Confirm the Authorization header actually arrives - some proxies drop it, particularly across a redirect.
  • Verify the token's iss and aud match what the API expects.
  • Send a WWW-Authenticate header with your 401s so clients know what to do.
  • If the credentials are valid and the user simply lacks permission, return 403 instead.

Headers this status expects

  • WWW-Authenticate - required by the specification, and commonly omitted. Names the scheme, e.g. Bearer realm="api".

Should a client retry?

Retry once after refreshing credentials. Retrying with the same credentials cannot succeed - and a client that loops on 401 without refreshing is a common cause of self-inflicted rate limiting.

FAQ

What is the difference between 401 and 403?
401 means unauthenticated - no valid credentials were supplied - and clients respond by authenticating or refreshing a token. 403 means authenticated but not permitted, so retrying with the same credentials is pointless. Using 401 for a permissions failure sends clients into a useless refresh loop.
Why is 401 called Unauthorized if it means unauthenticated?
A naming mistake that dates to the original HTTP specification and is now permanent. The specification text itself clarifies that it means authentication is required.
My token looks valid but I still get 401 - why?
Check, in order: exp against the current time in seconds; that the Authorization header survives your proxy; that iss and aud match what the API expects; and that the signing key has not rotated. Decoding the token shows the first three immediately.

Often confused with

  • 403 Forbidden The server understood the request and is refusing it - authentication will not help.
  • 400 Bad Request The server could not understand the request - it is malformed.