4xx Client error · RFC 9110 §15.5.2

401 Unauthorized

Authentication is required or the credentials sent are invalid.

What 401 means

Despite the name, 401 is about authentication: who you are. The response must carry a WWW-Authenticate header saying which scheme to use (Bearer, Basic).

Expired JSON Web Tokens, a missing Authorization header and wrong API keys are the everyday causes. When credentials are valid but insufficient, the correct code is 403.

Common causes

  • Missing Authorization header.
  • Expired or malformed token (check exp with a JWT decoder).
  • Wrong API key or password.
  • A proxy stripping the Authorization header.

How to fix it

  • Refresh or re-issue the token; compare exp with the server clock.
  • Confirm the header reaches the app (nginx: proxy_pass_request_headers on; Apache: CGIPassAuth on).
  • Match the scheme the server expects, e.g. Bearer .

What it looks like

A typical response:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api", error="invalid_token", error_description="The access token expired"

The same event in an nginx access log (the status is the number after the request line):

203.0.113.7 - - [10/Sep/2026:10:12:01 +0000] "GET /api/me HTTP/1.1" 401 153 "-" "Mozilla/5.0"

Check it with curl

-i prints the status line and headers, and -w '%{http_code}' prints only the number, which is handy in scripts and health checks. Replace the URL with yours:

curl -i -H 'Authorization: Bearer <token>' https://example.com/api/me

Compare what curl sees with what the browser sees. A different status from the same URL usually means a cache, a CDN edge or a cookie is in the way.

Investigating a run of 401s? Paste the log excerpt into Log Share to get line numbers, highlighting and an expiring link for whoever is on call with you.

  • 403Forbidden: The server understood the request and refuses to authorise it.
  • 407Proxy Authentication Required.
  • 400Bad Request: The server could not understand the request because it is malformed.

FAQ

401 or 403?

401 when the server does not know who you are or your credentials failed. 403 when it knows who you are and you are not allowed.

Why 401 right after login?

Usually the token is stored but not sent, is sent in the wrong header, or the server clock differs enough that iat is in the future. Decode the token and compare timestamps.