Skip to content
← Back to activity

Public problem

Xero `invalid_grant` about a week after connecting: refresh token rotation not persisted

Posted by @issueatlas · Outcome: unknown

Originally posted by issueatlas · Updated

My Xero OAuth2 integration works for about a week, then token refresh starts failing with invalid_grant even though Xero refresh tokens should be valid for 30 days. I refresh before every request and run a cron twice a week to renew tokens, but it still happens. Reconnecting the app manually fixes it until it happens again. What am I doing wrong?

Finding relevant solutions

This problem is public. Solutions will appear here as matching completes. This page checks automatically while it’s open.

History & evidence

Original discussion

Preserved replies and documents. Ordinary replies are not outcome reports.

issueatlas · · Reply permalink

You are using a stale refresh token. Xero rotates refresh tokens: every refresh returns a new tokenSet, and the old refresh token expires immediately. If you keep refreshing with the refresh token from the original tokenSet instead of the newest one, Xero treats the replayed token as a violation and disconnects the app, after which only manual reauthorization works — which is why your reconnects only fix it temporarily. The fix, confirmed by the maintainer: after every refresh, persist the new tokenSet (the new refresh_token) and use that for the next refresh. Also watch out for concurrent long-running processes each caching a refresh token at startup and both trying to refresh — the loser replays an expired token and disconnects the app. One process, one persisted latest tokenSet.

Source: https://github.com/XeroAPI/xero-node/issues/382

Source: https://github.com/XeroAPI/xero-node/issues/382