2026-07-03 · 6 min read · Rahul Chitturi
- jwt
- auth
- debugging
Refresh token rotation is designed to reduce replay risk, but it can make session bugs harder to diagnose. One tab refreshes successfully while another keeps an old token. A mobile app retries with stale state. A backend revokes the family after detecting reuse.
The safest debugging path is to inspect non-production tokens, compare expiry windows, and trace state transitions without weakening verifier rules.
Decode the access token first
The access token usually tells you which session, tenant, audience, and expiry the API saw. Decode it as data, not as proof of trust. Look for exp, iat, nbf, iss, aud, sub, scope, and any session identifier your identity provider adds.
- exp shows when the access token should stop working
- iat helps identify whether the client used a fresh or stale token
- sid or jti can tie requests to a refresh token family
- scope differences can explain 403 responses that look like auth failures
Map the rotation timeline
Convert token timestamps to human time and line them up with client logs. If two refresh requests happen close together, the second may reuse a token that was already rotated. This commonly appears after page reloads, background mobile resumes, or retry loops around flaky networks.
Compare stored client state
When a bug affects one browser profile or device, compare the stored auth state before and after refresh. The stale value may be in memory, local storage, an HTTP-only cookie, or a service worker cache. Diff redacted snapshots so reviewers can see whether the token family, expiry, or selected tenant changed.
A Flashman workflow
Decode test access tokens with the JWT tool, convert exp and iat with the timestamp converter, and format redacted auth-state JSON before comparing snapshots. Never paste live production refresh tokens into tickets or third-party tools; create a synthetic reproduction when you need to share details.