Also available in: Español · Português · Français · العربية
WWW-Authenticate parser: every challenge, not just the first
Paste a 401 response header and see each challenge, each parameter, and what the standard says about it.
What is the WWW-Authenticate header?
When a server answers a request with 401 Unauthorized, it must say how you could authenticate. That is the WWW-Authenticate header: a list of challenges, each naming a scheme such as Basic or Bearer and usually carrying parameters like a realm. The client picks a scheme it understands and replies with an Authorization header.
The header looks simple and is not. RFC 9110 says so itself, advising that user agents take special care in parsing it, because a value may contain more than one challenge, each challenge may carry a comma-separated list of parameters, and the header may be sent several times over. The separator between challenges and the separator between parameters are the same character, so nothing local tells you which one a given comma is.
This page implements the grammar from the specification, shows every challenge rather than the first, and names each parameter with the form it arrived in. It parses the challenge a server sends. It deliberately will not decode an Authorization header, which is the reply that carries your credentials.
How to use it
- Paste the header. With or without the field name, one per line if the response sent more than one. Several headers and a single comma-separated value are equivalent under the standard, so both give the same answer.
- Read the challenges. Each gets its scheme, whether that scheme is in the IANA registry, and a table of parameters showing whether each value arrived as a bare token, a quoted string, or a quoted string containing an escape.
- Check the notes underneath. They cover the things the standard has an opinion about: more than one challenge on a line, an unregistered scheme, a stray comma, a duplicate parameter, or a well-known scheme that is not listed first.
Why this header is hard to parse
The specification gives a worked example and then, unusually, tells you the answer. It shows a Basic challenge with a realm of simple, followed by a Newauth challenge with a realm of apps, a type parameter and a title parameter, all on one line. It states that this is two challenges and that type and title belong to the second one.
Working that out requires one token of lookahead. When the parser reaches type, nothing before it says whether that word begins a third challenge or names a parameter of the second. Only the next character decides: a token followed by an equals sign is a parameter, and a token followed by anything else is a new scheme. Miss that rule and you get a plausible-looking parse that is simply wrong.
The same example carries a second trap. Its title parameter is a quoted string that itself contains quotes, escaped with backslashes. A parser built around matching from one quote to the next stops in the wrong place, and a comma inside a quoted value will split a challenge that should have stayed whole.
This is not a theoretical concern. Two widely published parsers were tested against the specification's own example while this page was built. Neither returned the answer the specification prints: one reported a single challenge with the two realms merged together, and the other returned nothing at all, despite handling a plain Basic challenge perfectly. The standard anticipated it, warning that sending more than one challenge on a line might not be interoperable, and separately that many clients fail on a scheme they do not recognise.
What this deliberately will not do
It will not decode an Authorization header. WWW-Authenticate travels from the server and is public: it is the question. Authorization travels from the client and carries the answer, which for Basic is your username and password in a thin disguise. If you paste one here, the page says so and stops, without decoding it. That is the same position this site takes on its JWT decoder, which has no field for a signing secret: pasting a credential anywhere is a habit worth not forming, even into a page that runs entirely in your own browser.
It tells you what the grammar says, not what your client will do. A challenge can be perfectly valid and still be ignored, because a browser only implements a handful of schemes and a library may stop at the first challenge it recognises. Nothing here has been measured against a browser, and this page makes no claim about one.
It also does not judge a missing realm. It is tempting to treat that as an error, but the standard describes the realm parameter as reserved for schemes that wish to indicate a scope of protection, not as something every challenge must carry. Where the specification declines to require something, this page declines to warn about it.
One case is genuinely ambiguous and is reported rather than resolved. A trailing equals sign after a bare name, as in a challenge ending realm=, matches the grammar for an opaque token just as well as it matches a parameter whose value went missing, because that token production is a run of characters followed by any number of equals signs. Nothing at that point in the text distinguishes them. Where the standard leaves two readings open, so does this page.
Why is it free?
Parsing a header is string handling, and it runs in your browser. There is no server in the loop, so there is nothing to bill for and no account to create.
Nothing is uploaded. The header you paste never leaves the tab.