If you’ve ever had an integration run perfectly for a month and then quietly stop, this is probably why. Worth knowing before you build the next one.
What happens
Some OAuth2 providers hand back a new refresh token every time you refresh. The response carries a new access token and a new refresh token, and the one you started with is now dead.
If your workflow stores that original refresh token and keeps reusing it, everything works right up until the first refresh that actually matters. Then the provider rejects it and the integration stops. On a 30 day access token, that’s roughly a month after you built the thing and moved on.
Why it’s hard to spot
Three things conspire.
The error reads as an auth failure, so the natural reaction is to reconnect the account. Reconnecting issues a fresh refresh token, so it works again, for another 30 days. That makes it look intermittent rather than structural.
It doesn’t spike. If you alert on failure-rate spikes, one integration dropping to zero and staying there never trips anything. The rate is flat. It’s just flat at zero.
It’s per account. In a multi-account setup each one dies 30 days after it connected, so you get a slow trickle of unrelated-looking breakages instead of one obvious incident.
The fix
Persist the new refresh token in the same step that receives the refresh response, before anything downstream can fail. Not in a later node, not on a scheduled cleanup job. If the write happens anywhere other than immediately, there’s a window where you’ve spent a refresh token and haven’t saved its replacement, and that window is enough to lose the account.
If you’re on n8n’s built-in OAuth2 credential for a supported service, this is handled for you. It matters when you’ve built the flow yourself with HTTP Request nodes, which you have to do when the provider isn’t supported or the token endpoint URL is dynamic.
On storage: $getWorkflowStaticData(‘global’) is fine for a single account but isn’t safe once executions overlap. For multi-account, use an external store keyed by account.
How to detect it
Per-account success rate, not fleet-wide failure rate. Flag anything sitting at 0% for N days regardless of volume. A per-execution view shows you a long run of correctly reported errors and no anomaly at all, which is exactly why this survives so long in production.
Which providers do this
Pinterest does. Its refresh response returns a new refresh token alongside the new access token, and plenty of others behave the same way. Safest assumption is that yours might.
Cheapest way to find out: refresh twice in a row with curl and see whether the second call still accepts the original refresh token. Two minutes, and it tells you whether you need any of the above.