Saltar al contenido principal

Guías / Códigos de estado HTTP explicados

401 Unauthorized: what it means and how to fix it

A 401 Unauthorized means the request is missing valid credentials, or the credentials it sent were rejected. The server is not saying you are banned from the resource, only that it does not yet know who you are, and it expects you to authenticate before it answers the real question of what you are allowed to do.

What 401 Unauthorized means

RFC 9110 defines 401 as a request that requires authentication, either because none was supplied or because what was supplied did not pass. A 401 response must include a WWW-Authenticate header naming the scheme the server expects, such as Basic, Bearer, or Digest. That header is the clue most people skip past: it tells you exactly what kind of credential the server wants, which is usually faster than guessing.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api", error="invalid_token"

How the error appears

In a browser, a 401 protected by HTTP Basic authentication triggers the native username and password prompt, not a page rendered by the site. A 401 from a JSON API, by contrast, usually shows up only in a network tab or an error toast the application built for it, since there is no default browser chrome for a Bearer-token failure. From the command line, the credential and the header are both visible in one request:

curl -i -H "Authorization: Bearer eyJhbGciOi..." https://api.example.com/v1/account
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token", error_description="token is expired"

Server and application logs typically record the reason too, for example "token expired," "signature invalid," or "no Authorization header," which narrows the cause faster than the generic status code alone.

What causes a 401 Unauthorized

Roughly in order of how often each one turns out to be the cause:

  • No credentials sent at all. A logged-out session, a missing API key, or a client that never attached the Authorization header in the first place.
  • An expired token. Session cookies, OAuth access tokens, and JWTs all carry a lifetime, and a client using a stale one gets 401 even though it worked minutes earlier.
  • Clock skew between client and server. A JWT's exp and nbf claims are evaluated against the server's clock. A server or client with the wrong time can reject a token that is, by the token's own math, still valid, or accept one that already expired.
  • The wrong authentication scheme. Sending Authorization: Basic ... to an endpoint that expects Bearer, or the reverse, fails even though a header is present.
  • An API key placed in the wrong location. Some APIs expect the key in a custom header like X-API-Key, others in Authorization, and others as a query parameter. Putting a valid key in the wrong spot looks identical to sending no key at all.
  • A reverse proxy or gateway stripping the Authorization header. Some proxy and CDN configurations drop headers they do not explicitly forward, and a perfectly valid credential never reaches the origin.
  • Revoked credentials. A user changed their password, an admin rotated an API key, or a token was explicitly invalidated on logout.

401 versus 403

The two are often confused because both refuse the request, but the spec draws a clear line. A 401 means the server needs you to authenticate, and a valid credential could change the outcome; it must carry WWW-Authenticate. A 403 means the server understood exactly who you are and is refusing anyway, for a reason authentication cannot fix, such as a role or plan restriction. If logging in again would plausibly help, it should be 401. If the user is already logged in and simply is not allowed, it should be 403, though in practice plenty of APIs use 401 loosely for both cases.

How to tell whose fault it is

If you are the one calling the API, reproduce the request with a fresh credential from a clean environment; if a newly issued token succeeds, the old one had simply expired or was revoked. If a brand-new token also fails, check the scheme and the header name against the API's documentation before assuming the server is broken. If you run the service and users report 401s that you cannot reproduce with your own account, the fastest way to separate "the server is fine, individual tokens are stale" from "authentication itself is broken for everyone" is to run an HTTP check with a known-good credential from several locations at once and compare the results.

How to fix a 401 Unauthorized

If you are a visitor

  1. Log in again. Most 401s from a web app are simply an expired session, and signing in refreshes it.
  2. Check the system clock on your device if the same login keeps failing immediately after you authenticate. A clock several minutes off can invalidate time-based tokens on some clients.
  3. Regenerate an API key or token from the account settings if you suspect it was rotated or revoked, rather than assuming your integration code has a bug.
  4. Confirm the Authorization header is actually being sent, using your browser's network tab or a plain curl call, since some HTTP client libraries silently drop custom headers on a redirect.

If you run the site

  1. Read the WWW-Authenticate header and your own logs for the specific rejection reason before changing anything; "expired," "invalid signature," and "missing header" each point at a different fix.
  2. Check clock synchronization on the servers issuing and validating tokens. NTP drift on either side is a classic, intermittent cause of JWT rejections that otherwise look random.
  3. Verify the proxy or load balancer forwards the Authorization header. A rule added for an unrelated reason can silently strip it for every request behind that hop.
  4. Document the expected scheme and header name clearly in your API docs, and return a specific error_description in the WWW-Authenticate header so integrators do not have to guess.
  5. Distinguish 401 from 403 in your own responses where it matters to callers, so client code can tell "refresh your token" apart from "you will never be allowed to do this."

How to prevent a silent 401 outage

A 401 caused by an expired signing certificate, a clock that drifted out of sync, or a proxy change that started dropping the Authorization header will not look like a crash. The service answers instantly and correctly by its own rules, so it can sit broken for every caller until someone notices. An HTTP check with an assertion on the expected status code, run with a live credential against an authenticated endpoint, catches that the moment it starts happening. For APIs specifically, pairing that with API monitoring that checks response bodies as well as status codes catches a token that authenticates but returns malformed data too.

See 403 Forbidden for requests the server understood and refused regardless of credentials, the 4xx overview for the wider family of client errors, and the other guides in this batch: 405 Method Not Allowed, 422 Unprocessable Content.

Frequently asked questions

Why do I get 401 right after logging in successfully?

Usually a clock mismatch between your device and the server, or a client that cached the old, now-invalid token instead of using the freshly issued one. Confirm your system time is correct and that the new token is actually being sent.

Does 401 mean my account was hacked?

Not on its own. It almost always means an expired session, a revoked key, or a header sent incorrectly. Only treat it as a security concern if you did not expect the credential to stop working and cannot explain why it did.

What is the difference between 401 and an authentication failure at the TLS layer?

A TLS client certificate failure prevents the connection from being established at all, so no HTTP status code is ever returned. A 401 means the connection succeeded and the server received a full HTTP request, then rejected it at the application layer for lacking valid credentials.

Should a login form itself ever return 401?

No. A login endpoint evaluating a username and password is not authenticating an existing request; a wrong password there is conventionally a 400 or a 200 with an error payload, since the endpoint's whole purpose is to accept unauthenticated attempts and judge them.

Can a valid API key still produce 401?

Yes, if it is sent in the wrong header or the wrong scheme, if it was rotated after your integration cached the old one, or if the request reached the server through a proxy that dropped the header before forwarding it.

Compruébalo ahora

Ejecuta la comprobación gratuita en tu propio sitio, sin necesidad de cuenta.

HTTP check

Monitoriza esto de forma permanente

Recibe un aviso en cuanto algo falle: HostTracker comprueba desde más de 300 ubicaciones y te avisa por correo, SMS, Slack, Telegram y más.

Funciones de HostTracker

Más en esta sección: Códigos de estado HTTP explicados