# WWW-Authenticate Header — Syntax, Values & Examples

> Sent with a 401 to tell the client which authentication scheme to use, and sometimes why the last attempt failed.

A [401 Unauthorized](https://www.devkult.com/http/401.md) response should include WWW-Authenticate, naming the scheme the client should use. With `Basic`, browsers show their built-in login dialog. With `Bearer`, OAuth servers add an `error` parameter that tells clients whether to refresh the token or give up.

- Type: Response header
- Category: Authentication & cookies
- Defined in: [RFC 9110 §11.6.1 — WWW-Authenticate](https://www.rfc-editor.org/rfc/rfc9110.html#section-11.6.1)

## Syntax

```http
WWW-Authenticate: <scheme> realm="<realm>"[, <param>="<value>"]
```

## Values

| Value | Meaning |
|---|---|
| `Basic realm="…"` | username and password; browsers show a login prompt |
| `Bearer` | send an access token |
| `Bearer error="invalid_token"` | the token is expired, revoked or malformed |
| `Bearer error="insufficient_scope"` | valid token, missing permissions (sent with 403) |

## Examples

```http
WWW-Authenticate: Bearer realm="api", error="invalid_token", error_description="The access token expired"
```

tells the client to refresh its token

```http
WWW-Authenticate: Basic realm="Staging", charset="UTF-8"
```

a password-protected staging site

## Good to know

- To avoid the browser's login dialog in a single-page app, don't send `Basic` — use `Bearer` or a custom scheme.
- Cross-origin JavaScript can only read this header if you list it in `Access-Control-Expose-Headers`.

## How to set WWW-Authenticate

### Express

```
res
  .status(401)
  .set("WWW-Authenticate", 'Bearer realm="api", error="invalid_token"')
  .json({ error: "invalid_token" });
```

### Next.js (route handler)

```
return Response.json(
  { error: "invalid_token" },
  {
    status: 401,
    headers: { "WWW-Authenticate": 'Bearer realm="api", error="invalid_token"' },
  },
);
```

### nginx (Basic auth)

```
location / {
  auth_basic "Staging";  # sends WWW-Authenticate: Basic realm="Staging"
  auth_basic_user_file /etc/nginx/.htpasswd;
}
```

## Check it

Fetch only the response headers and filter for WWW-Authenticate. In the browser, it's under Response Headers in DevTools → Network.

```sh
curl -sI https://example.com/ | grep -i '^www-authenticate:'
```

## FAQ

### Is WWW-Authenticate required on a 401?

The HTTP specification requires it. Many JSON APIs leave it out, which works in practice, but sending it tells clients how to fix the request.

## Status codes it appears with

- [401 Unauthorized](https://www.devkult.com/http/401.md)
- [407 Proxy Authentication Required](https://www.devkult.com/http/407.md)

## Related headers

- [Authorization](https://www.devkult.com/headers/authorization.md): Carries the client's credentials — a bearer token, Basic username and password, or another scheme.
- [Set-Cookie](https://www.devkult.com/headers/set-cookie.md): Stores a cookie in the browser, with attributes that control its lifetime, scope and security.

Open the interactive page: https://www.devkult.com/headers/www-authenticate