Invalid DPoP Proof
URI: https://docs.ankatech.co/errors/invalid_dpop_proof
HTTP Status: 400 Bad Request (token endpoint) · 401 Unauthorized (Admin API)
This error corresponds to the RFC 9449 OAuth 2.0
errorcodeinvalid_dpop_proofof the same name. The RFC 9457typesuffix uses the identical underscore form so the two identifiers match.
When you see this
An administrative workload* sent a DPoP proof (RFC 9449) that was refused. A proof is a fresh JWS that binds one request to the key the workload's token is bound to.
- At the token endpoint (
POST /api/v3/auth/token) the answer is400with the body below. The proof is checked before any credential, so no credential was examined and no token was issued. - At the Admin API the answer is
401withWWW-Authenticate: DPoP error="invalid_dpop_proof", algs="ES256 ES384 PS256 RS256"and the Admin API's unauthenticated problem body. Nothing changed.
Common Causes
- No
DPoPheader, or more than one. typis notdpop+jwt; the algorithm isnone, an HMAC or anything butES256,ES384,PS256,RS256; thejwkheader carries a private member; the signature does not verify.htmis not the request's method, orhtuis not the request's public URL. At the token endpointhtumust equal thetoken_endpointof the authorization server metadata; at the Admin API, the public URL of the request without query or fragment.iatis more than 60 seconds old or more than 5 seconds in the future (check the client clock).- The proof's
jtiwas already used: every request needs a new proof. - At the Admin API:
athis not the hash of the presented token, or the proof key is not the key the token is bound to (cnf.jkt).
Response Example
{
"error": "invalid_dpop_proof",
"error_description": "The DPoP proof is invalid",
"error_uri": "https://docs.ankatech.co/errors/invalid_dpop_proof",
"type": "https://docs.ankatech.co/errors/invalid_dpop_proof",
"title": "Invalid Dpop Proof",
"status": 400,
"detail": "The DPoP proof is invalid",
"instance": "/api/v3/auth/token",
"timestamp": 1730000000
}
Content-Type: application/json at the token endpoint, as for every RFC 6749 §5.2 token error. The Auth API carries no correlation member in the body: correlate through the X-Correlation-Id response header.
How to Resolve
- Build a new proof for every request, with a fresh
jtiand the current time asiat. - Take the token endpoint URL for
htufromGET /api/v3/auth/.well-known/oauth-authorization-server(token_endpoint), never from the address you happen to dial. - Sign every proof with the same key the token was issued for, and include
athon Admin API requests. - The Key Management SDK and the Key Management CLI build proofs for you; prefer them to hand-written clients.
For full schema definitions, examples, and interactive testing, see the Developer Hub Reference.