# use_dpop_nonce

The DPoP proof must carry a nonce from this server; retry with the one supplied (RFC 9449 §8, §9).

## Meaning

The server requires a nonce in every DPoP proof. A proof with no nonce, or with one that
is stale or from another organization, is answered with this code and a `DPoP-Nonce`
header holding the nonce to use: `400` with an OAuth error body at `/token`, `401` with a
`WWW-Authenticate: DPoP` challenge at `/userinfo` and other protected resources. At
`/register` the body says `invalid_token` and the challenge says `use_dpop_nonce`.
A nonce stays valid for five minutes.

## Impact

Normal protocol flow: the first DPoP request of a client, and the first after its nonce
expires, gets this answer. It becomes a problem only when a client does not retry with
the supplied nonce.

## Diagnosis

1. The response carries `DPoP-Nonce`; check the client reads it and signs it into the
   next proof.
2. Recorded with reason `use_dpop_nonce` and cause `dpop_nonce_missing` or
   `dpop_nonce_stale`. A client that never succeeds shows these in pairs without a
   success after them.

## Mitigation

- As a client developer: on this code, build a new proof with the `nonce` claim set to
  the `DPoP-Nonce` value and resend once. Keep the nonce from each successful response
  for the next request.
- As an operator: nothing to do; if the server cannot issue a nonce it answers
  `server_error` instead.
- As a user: nothing to do.

## Escalation

If a proof carrying the nonce just supplied is answered this way again, open an issue
with both request ids and the server version. Never attach proofs or tokens.

---

[OAuth error runbooks](https://www.nauthera.io/docs/v1/runbooks/oauth) · Generated from [`internal/runbook/oauth.yaml`](https://github.com/nauthera/nauthera-server/blob/main/internal/runbook/oauth.yaml) in nauthera-server.
