OAuth 2.0 Token Exchange Returns invalid_grant

LIL Tinder 60 Reputation points
2026-10-05T10:02:17.17+00:00

A mobile client intermittently receives an invalid_grant error when exchanging a refresh token for a new access token. The issue appears after the app has been running for an extended period or after users sign in on multiple devices. Access tokens work normally until the refresh flow fails. What’s the best way to troubleshoot the token lifecycle, including refresh token expiration, rotation, reuse detection, revocation, and session policies?

Windows for business | Windows 365 Enterprise
0 comments No comments

2 answers

Sort by: Most helpful
  1. Chen Tran 13,270 Reputation points Independent Advisor
    2026-10-05T11:01:36.74+00:00

    Hello LIL Tinder,

    Thank you for posting question on Microsoft Windows Forum!

    Based on the issue description. Well! The plausible explanation to this behavior is that the intermittent invalid_grant error on a mobile client after extended runtimes or multi-device sign-ins typically stems from Refresh Token Rotation race conditions (concurrency) or Authorization Server session/rotation policies (such as token family invalidation via reuse detection). When a refresh token is rotated, any re-use of the previous token or concurrent requests using stale tokens causes the server to reject the grant and potentially revoke the active session.

    The suggestion here is to audit client-side refresh concurrency. If the mobile app has multiple background threads or concurrent network calls attempting to refresh an expired access token simultaneously, they will submit the same refresh token. Under Refresh Token Rotation, the authorization server invalidates the old token and issues a new one on the first request. Subsequent concurrent requests then submit the old token, triggering invalid_grant and potentially revoking the entire token family. Implement a "single-flight" mutex or token queue so only one refresh request executes at a time, while concurrent callers await the resulting token. You can verify success by inspecting client network logs during high-concurrency background syncs to ensure only one token endpoint request is dispatched per refresh cycle.

    Another suggestion is to check multi-device session and token family policies. When users sign in on multiple devices, identity providers often enforce policies like maximum concurrent sessions, single-session limits, or strict token family revocation where reusing an older token invalidates sibling tokens across all clients. Review your IdP's session management configuration to see if a login on a secondary device explicitly revokes or displaces the refresh token family issued to the primary device. Try to verify this by checking identity provider audit logs to see if an invalid_grant corresponds directly to a subsequent sign-in event from another device.

    It is also worth examining whether the error occurs strictly after a fixed time window (absolute lifetime) or period of app inactivity (idle timeout). The fact is that many authorization servers enforce maximum refresh token lifetimes or sliding windows regardless of usage. Try to compare the timestamp when the initial token was issued against the exact moment the invalid_grant occurs to see if it matches the IdP's configured max-age or idle limit.

    For further reference.

    Hope the above information is helpful!

    Was this answer helpful?

    0 comments No comments

  2. AI answer

    2026-10-05T10:02:37.3366667+00:00

    Use the token endpoint response and sign-in conditions to separate five common causes of invalid_grant during refresh:

    1. Expired or invalid refresh token
      • A refresh token can expire, be revoked, or no longer have sufficient privileges.
      • When that happens, the app must handle the token endpoint error and start a new interactive sign-in flow.
      • For Microsoft identity platform, invalid_grant means the grant is invalid or expired and a new authorization request is required.
    2. Refresh token rotation
      • When a new refresh token is returned, replace the old one immediately.
      • Old refresh tokens are expected to be discarded after a successful refresh.
      • If the app keeps using an older stored token after a newer one was issued, intermittent refresh failures can occur.
    3. Multi-device and public client behavior
      • For public clients, refresh tokens can be device-bound in some scenarios.
      • If users sign in on multiple devices, verify that each device stores and uses its own latest refresh token and does not overwrite another device’s token state.
      • Do not assume a refresh token will remain valid for any fixed period; the app should always be prepared for reauthentication.
    4. Session and platform lifetime limits
      • Single-page apps using a redirect URI registered as spa have refresh tokens that expire after 24 hours and must rerun the authorization code flow interactively every 24 hours.
      • For mobile and desktop public client scenarios in the provided guidance, there is no supported way to extend a 24-hour inactivity window when that behavior applies.
      • Conditional Access persistent session settings affect browser sessions, not mobile or desktop app token lifetimes.
    5. Revocation and policy-driven invalidation
      • Refresh tokens can become invalid after events such as password changes, admin revocation, session reset, or renewed consent requirements.
      • In those cases, the correct recovery path is reauthentication.

    A practical troubleshooting flow:

    1. Capture the full token error payload
      • Log error, error_description, error_codes, timestamp, trace_id, and correlation_id from the /token response.
      • These fields are the primary diagnostics for token endpoint failures.
    2. Verify the refresh request itself
      • Confirm the request includes the required refresh token grant parameters.
      • Missing required parameters cause invalid_request, while an expired or invalid grant causes invalid_grant.
    3. Audit refresh token storage and replacement logic
      • After every successful refresh, check whether a new refresh_token was returned.
      • If returned, persist it atomically and stop using the previous token.
      • This is the most important check for long-running apps and intermittent failures.
    4. Correlate failures with user events
      • Check whether failures started after password changes, sign-ins on another device, consent changes, or admin/session revocation.
      • If yes, treat the token as no longer recoverable and force sign-in.
    5. Check client type assumptions
      • If the app is a mobile or desktop public client, do not design around a guaranteed long refresh token lifetime.
      • If the app spans devices or regions, verify the registration model matches the app architecture, because some public-client refresh tokens are only guaranteed to refresh on the same device.
    6. Handle failure correctly in code
      • On invalid_grant, stop retrying the same refresh token in a loop.
      • Clear the cached invalid token set and trigger a fresh authorization flow.
    7. Do not inspect token contents for APIs not owned by the app
      • Use the token endpoint response and server-side error metadata for diagnostics instead of relying on token parsing assumptions.

    If the app uses Azure App Service authentication, also distinguish between the App Service session and the identity provider token:

    • App Service authenticated session: 8-hour session with a default 72-hour grace period, refreshable through /.auth/refresh.
    • Identity provider access tokens: no grace period after expiry.

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.