errors.x7.al › HTTP status codes

401 Unauthorized

401 Unauthorized is an HTTP status code sent when a request lacks valid authentication credentials for the target resource. Despite the name, it does not mean the request was forbidden — it means the server does not know who you are, or the credentials you supplied were missing, malformed, or expired. A response carrying this code includes a WWW-Authenticate header that tells the client how to authenticate.

Advertisement

What it means

The two words to keep apart here are authentication and authorisation. Authentication answers "who are you?"; authorisation answers "what are you allowed to do?". A 401 is the first question: the server needs proof of identity before it will even consider the request. The client is expected to retry, and the retry is expected to carry credentials — a username and password, a session cookie, an API key, or a bearer token. If the retry still fails, the credentials were rejected or never arrived.

The neighbouring code, 403 Forbidden, is the second question. A 403 means the server recognised the client but the action is not permitted, and sending credentials again would change nothing. That is why a 403 has no WWW-Authenticate invitation while a 401 does. In short: 401 is "log in" and 403 is "you may not do this". Mixing the two up sends debugging in the wrong direction, so always check which code is actually returned and which headers come with it.

APIs often use 401 for a missing or expired token and 403 for a token that is valid but under-privileged. So when you meet a 401, suspect the credential itself: not sent, expired, scoped to the wrong audience, or signed incorrectly. The resource is probably fine; the key you used to reach it is the problem.

Common causes

  • No credentials were sent, or the browser's saved login is missing after a session expired.
  • The username or password is wrong, and the server declines to say which one.
  • An API key or bearer token is absent, expired, revoked, or was signed for a different audience or environment.
  • A reverse proxy or CDN is stripping the Authorization header before the application sees it.
  • Clock drift or a realm mismatch breaks digest or signed-request authentication even when the secret is correct.

How to fix it

  1. Log in again. For a website, clear the stored session for that site and sign in afresh; an expired cookie is the single most common cause of a 401.
  2. Verify the credentials reach the server. Inspect the request headers to confirm the Authorization header is actually present:
    curl -i -u user:pass https://example.com/api/me
    # or with a bearer token:
    curl -i -H "Authorization: Bearer $TOKEN" https://example.com/api/me
  3. Renew API tokens. Refresh the token, check its expiry and scope, and make sure you are using the matching key for the environment. A token minted for staging will not be accepted in production.
  4. Check the proxy chain. Confirm that Nginx, Apache, or your CDN forwards the Authorization header rather than dropping it. On Nginx the setting is explicit:
    proxy_set_header Authorization $http_authorization;
    proxy_pass_request_headers on;
  5. Check the clock and the realm. For digest or HMAC-signed requests, keep server and client clocks in sync with NTP and make sure the realm string matches on both sides.
Advertisement

How to prevent it

Prefer token-based authentication with short-lived access tokens and a refresh flow over long-lived passwords, and handle expiry in the client so users are re-prompted before a request fails rather than after. Never hard-code credentials in code or config files; keep secrets in a manager or environment variables.

On the server, return 401 only when authentication is genuinely required, include a correct WWW-Authenticate header naming the scheme, and log authentication failures so you can spot a wave of expired tokens before your users start complaining. Also confirm that your proxy and CDN preserve the headers auth depends on, because a stripped header looks exactly like a wrong password from the client's side.

Advertisement