Glossary

HTTP 401 Unauthorized

HTTP 401 Unauthorized tells the client that the request lacked valid authentication credentials for the target resource. Despite the name, it is about authentication — who you are — rather than authorisation, which is what 403 covers. A correct 401 carries a WWW-Authenticate header naming the scheme the server will accept, which is what lets a client know what to send next rather than guessing.

401 and 403 answer different questions

401 says the server does not know who is asking. Sending valid credentials may change the answer.

403 says the server knows who is asking and is refusing anyway. Sending the same credentials again will not change anything.

So a 401 is an invitation to authenticate and a 403 is a refusal, which is why returning the wrong one sends clients into a retry loop or stops them retrying when they should.

An expired token is a 401: the credential is no longer valid, so re-authenticating is the right response.

A valid token belonging to an account without access to that resource is a 403.

The header that makes it actionable

The specification requires a 401 to carry a WWW-Authenticate header naming at least one authentication scheme.

Without it a client is told authentication is needed and not which kind, which in practice means a human has to read documentation before writing the retry.

The header can carry parameters — a realm, an error code, a description — which is how a token-based API distinguishes an expired credential from a malformed one.

Many APIs omit it entirely. That is a specification violation with a mild practical cost, and it is the most common defect around this status code.

What a good 401 body contains

A stable machine-readable identifier the client can branch on, rather than a sentence that changes when someone improves the wording.

Enough detail to distinguish missing from expired from malformed, because those lead to three different client behaviours.

Nothing about why the credential was rejected beyond that, since detail here helps an attacker refine attempts more than it helps a legitimate caller.

No stack trace and no internal path, which is true of every error response and easiest to get wrong on an authentication failure.

How it is observed

Endpoints answering 401 without credentials are recorded as behaving correctly — the check reports them as evidence that access control works, not as a finding.

An endpoint returning 200 with an empty payload where a 401 was expected is the opposite, and it is the case worth investigating.

A 401 from a protection layer is indistinguishable from a 401 from the application when observed from outside.

Nothing is ever sent to try to satisfy a 401: no credential is guessed, supplied or tested.

Frequently asked questions

Should I return 401 or 403 for an expired token?
401. The credential is no longer valid, so re-authenticating is the correct next step — which is exactly what a 401 asks for.
Is the WWW-Authenticate header mandatory?
The specification requires it on a 401. Plenty of APIs omit it, which leaves clients unable to discover which scheme to use without reading documentation.
Does a 401 mean my endpoint is secure?
It means it refuses anonymous requests, which is the first requirement and not the whole of one. What happens with a valid credential is outside what an anonymous observation can see.

Sources

Related

VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.

Scan a website