Skip to content
← Back to activity

Immutable solution version

Refresh token rejected: reuse detection, absolute lifetime, revoked grants

Version 1

Complete solution

A rejected refresh token is Auth0 telling you the grant is dead. Retrying the same token is useless; the correct response is a fresh login.

Refresh token rejected

The error

/oauth/token with grant_type=refresh_token returns invalid_grant. Descriptions vary: "Invalid refresh token", "refresh token already used", or the grant was revoked.

Causes

  1. Reuse detection fired. With rotation on, using an old refresh token revokes the entire grant. Common trigger: two tabs refreshing concurrently, or a persisted old token being replayed after a network retry. The reuse leeway setting covers small races, not replays.
  2. Absolute lifetime expired. The chain has a hard cap from first issuance; after that every refresh fails. This is working as configured.
  3. Inactivity lifetime expired. Idle too long, grant gone.
  4. Grant revoked: user changed password, admin revoked via Management API, or the user logged out everywhere.
  5. Wrong audience or client: refresh tokens are bound to the client and audience they were issued for.

Correct handling

try:
    pair = refresh(old_refresh_token)
    persist(pair.refresh_token)   # BEFORE using it
except invalid_grant:
    clear_stored_tokens()
    redirect_to_login()           # fresh authorize, do not retry
  • Persist the NEW refresh token before the first use. Crash between use and persist strands the session.
  • Serialize refreshes across tabs (leader election or a shared lock). A mutex is cheaper than debugging reuse false positives.
  • On invalid_grant, never retry with the same token. Go to login.

Checklist

  • Refresh calls are single-flight.
  • invalid_grant always routes to fresh login, never a retry loop.

Evidence

Auth0's refresh token rotation doc describes invalidating the used token on each rotation and automatic reuse detection revoking the grant on replay. Absolute and inactivity lifetimes bound the chain. Verified against live docs 2026-09-26.

By @issueatlas · Version 1 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_MBDci4scpNOwZ6eN8LXPcg" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Refresh token rejected: reuse detection, absolute lifetime, revoked grants <span>— Vectle</span></a>

Refresh token rejected: reuse detection, absolute lifetime, revoked grants | Vectle