← Debugging Guides

阅读中文版本

HTTP 401 Unauthorized and WWW-Authenticate

Diagnose HTTP 401 Unauthorized by reading the WWW-Authenticate header, checking token format, and distinguishing expired tokens from missing credentials.

intermediatedebugginghttpauthapi

Symptoms

  • HTTP 401 with WWW-Authenticate: Bearer realm=...
  • Requests work after logging in again but fail after a timeout
  • The client sends a token yet still receives 401

Possible causes

  • No Authorization header is sent at all
  • The token is expired, malformed, or signed with the wrong key
  • The scheme is wrong (Basic vs Bearer) or includes stray whitespace
  • A clock skew makes a freshly issued token appear expired

Diagnosis steps

Read the WWW-Authenticate challenge

Interpretation

It names the expected scheme and often an error code such as invalid_token, telling you why authentication failed.

Decode the token payload

jwt decode <token> (or base64 the middle segment)

Interpretation

Check exp, iss, and aud against the server expectations; a wrong audience or issuer causes rejection.

Confirm the header format

Interpretation

Authorization: Bearer <token> with exactly one space; a missing scheme or extra whitespace is rejected.

Root cause

A 401 means the request lacks valid authentication credentials. The WWW-Authenticate header is the server explaining how to authenticate and, with an error parameter, why the attempt failed. A token can be present but invalid because it is expired, signed by another key, or destined for a different audience.

Fix

Send a correctly formed Authorization header with the right scheme, refresh tokens before expiry, and align issuer, audience, and signing keys between the token issuer and the verifier. Where clock skew is possible, allow small leeway on exp. Never treat 401 as retryable with the same token; obtain a fresh credential first.

Verify the fix

Replay the request with a freshly issued token; it returns 200, and the WWW-Authenticate error parameter no longer appears in the response headers.

Symptoms

The API returns 401 Unauthorized alongside WWW-Authenticate: Bearer. It may appear only after a session ages, or from a particular client that handles headers differently.

Diagnosis

Read the challenge and decode the token:

curl -i https://api.example.com/me
# WWW-Authenticate: Bearer realm="api", error="invalid_token"

# decode the payload (middle segment) to inspect claims
echo '<payload>' | base64 -d

Check exp, iss, and aud against the verifier configuration.

Fix

Send the right scheme and refresh on time:

curl -H 'Authorization: Bearer eyJ...' https://api.example.com/me

Align signing keys and allow small clock leeway.

Verification

Retry with a fresh token; the endpoint returns 200 and the response no longer includes an error in WWW-Authenticate, confirming the credential is now valid.

401 Versus 403

These two codes are often confused, and telling them apart dictates the fix. A 401 means the request lacks valid credentials: send a token, refresh an expired one, or correct its signature. A 403 means the credentials are valid but the identity is not permitted. Clients should retry a 401 only after acquiring new credentials, never by repeating the same request, and they should treat a 403 as a permission problem rather than an authentication one. A server that returns 401 for a permission failure misleads well-behaved clients into pointless token refreshes.