invalid_grant on Refresh Token Retry After Network Timeout During Rotation
0 reputation · 09 May 2024, 19:53 UTC
0 reputation · 09 May 2024, 19:53 UTC
A client uses the OAuth 2.0 Refresh Token grant (RFC 6749, Section 6) against an authorization server that enforces Refresh Token Rotation, as recommended by the OAuth 2.0 Security Best Current Practice. Each successful refresh invalidates the previous refresh token and issues a new one.
When the client sends a refresh request and the network times out, the server may have already processed the request, rotated the token, and stored the successor. Because the client never received the response, it retries with the now-invalidated token and receives invalid_grant. With strict rotation and no grace period, this can permanently destroy the session even though the client behaved correctly.
RFC 6749 defines no idempotency mechanism for token requests, and retry behavior is left to implementers. Some servers reportedly allow a short grace window in which the prior refresh token remains accepted, but the duration and semantics vary.
How should a client distinguish a genuine invalid_grant (revoked or expired token) from one caused by its own retry of an already-rotated token? Is a server-side grace period for rotated tokens the accepted mitigation, and if so, what window is considered safe? Should clients instead persist the newest token transactionally before any retry, and what does the BCP actually require here?
29275 reputation · 09 May 2024, 20:51 UTC
The error response invalid_grant alone does not let a client tell whether the refresh token was genuinely revoked/expired or merely already rotated by a prior request that timed out. RFC 6749 provides no idempotency token or distinct error code for this case, and the OAuth 2.0 Security BCP (RFC 9700) does not mandate a way to differentiate them.
invalid_grant.invalid_grant, treat the grant as unrecoverable: stop using the refresh token, keep any still‑valid access token until it expires, and initiate a recovery flow (e.g., redirect the user to re‑authenticate).If the authorization server implements one of the following, the client can safely retry:
In that scenario, after a timeout the client may retry the same request; if the server accepts it within the grace period or rejects it due to sender‑constraint mismatch, the client can distinguish the outcomes.
Ask the server administrator (or consult its documentation): Does the authorization server provide a grace period for rotated refresh tokens or support sender‑constrained refresh tokens? If the answer is yes, follow the retry‑with‑back‑off approach; if no, fall back to the recovery flow described above.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.