Confluence OAuth refresh token invalid_grant — What it means & how to fix it

How to diagnose and fix Confluence refresh token invalid_grant errors

Table of contents

Confluence integrations that sync spaces, pages, or knowledge-base content rely on a healthy OAuth token lifecycle. Your token refresh request starts returning invalid_grant. Scheduled syncs stall, writes fail, and users experience a “disconnected Confluence” state until you repair the grant.

This article shows how to identify Confluence refresh-token failures, explains the Atlassian-specific reasons they happen (rotating refresh tokens + concurrency), and outlines practical fixes so they don’t keep recurring. For more background, see API Auth Is Deeper Than It Looks and Why is OAuth still hard in 2025?.

Spot the error

Even if you search for “Confluence OAuth”, the OAuth authorization server is Atlassian. Token refresh happens against auth.atlassian.com, and Confluence API calls go via api.atlassian.com (not {your-site}.atlassian.net). In other words, Confluence shares the same OAuth setup as Jira: same token endpoint, different API routing.

When your backend refreshes tokens:

  • Token endpoint: https://auth.atlassian.com/oauth/token
  • Often HTTP status: 403
  • OAuth error: invalid_grant

Example response payload (shape):

Atlassian OAuth refresh error response (Confluence)

📋

{
  "error": "invalid_grant",
  "error_description": "Token has been expired or revoked."
}
  

Atlassian’s docs often phrase this as: “Unknown or invalid refresh token.” Practically, it means the refresh token you’re presenting can’t be exchanged for a fresh token pair. Replaying that same refresh token usually won’t recover the connection.

Why did Confluence/Atlassian reject the refresh token?

For Confluence Cloud OAuth (3LO), invalid_grant is almost always a token lifecycle issue. The root causes are usually not Confluence-specific — they’re Atlassian OAuth-specific.

Most common: you didn’t persist the rotated refresh token

Atlassian uses rotating refresh tokens: every successful refresh returns a replacement refresh token, and invalidates the one you just spent. If your app continues using the previous value, the next refresh attempt fails.

Common triggers include:

  • Your code stores the access token but fails to persist the new refresh token
  • A retry replays the same refresh token after a timeout

Two refresh attempts overlap (concurrency)

If multiple workers refresh the same Confluence connection concurrently:

  • Worker A refreshes and stores the new refresh token
  • Worker B refreshes with the now-disabled refresh token
  • Result: invalid_grant (and sometimes state corruption if writes aren’t atomic)

If you want the practical patterns for this, see How to handle concurrency with OAuth token refreshes.

The refresh token hit inactivity expiry

Atlassian rotating refresh tokens have an inactivity expiry window (commonly 90 days by default). If the integration is idle longer than that window, refresh fails and the user must re-authorize.

The user revoked the app grant

If the user revokes access to your 3LO app, refresh tokens stop working for that grant. The fix is to restart the authorization flow.

The user’s Atlassian account password was changed

Atlassian explicitly lists password changes as a reason the refresh-token exchange can return invalid_grant.

Wrong client credentials / wrong 3LO app

Using the wrong client_id/client_secret (wrong environment, a rotated secret not deployed, or simply the wrong 3LO app) can also cause refresh failures.

How to fix it

1) Persist the rotated refresh token (every refresh)

On every successful refresh, replace the stored refresh token with the new refresh token Atlassian returns.

2) Single-flight refresh per connection

Ensure only one refresh is in flight per connection. Everyone else should wait and reuse the updated token set. Persist (access_token, refresh_token, expires_at) together.

3) Verify the Atlassian OAuth endpoints (Confluence uses Atlassian OAuth)

Core endpoints:

  • Authorize: https://auth.atlassian.com/authorize (with audience=api.atlassian.com and offline_access)
  • Token + refresh: https://auth.atlassian.com/oauth/token

Confluence request routing:

  • Get cloudid: https://api.atlassian.com/oauth/token/accessible-resources
  • Call Confluence APIs: https://api.atlassian.com/ex/confluence/{cloudid}/{api}

Note: {api} is the Confluence REST path (for example, Confluence Cloud commonly uses /wiki/rest/api/... routes). If you’re calling {site}.atlassian.net/wiki/rest/... with a 3LO access token, you’re using the wrong base URL for OAuth 2.0 (3LO). If you’re also integrating Jira in the same product, see Jira OAuth refresh token invalid_grant — What it means & how to fix it.

If you’re debugging callback URLs locally, see 3 easy ways to do OAuth redirects on localhost (with HTTPS).

4) If it’s terminal: re-auth (don’t retry forever)

After you’ve ruled out stale refresh tokens, concurrency, and credentials:

  • Flag the connection as “needs re-auth”
  • Stop scheduled sync jobs for that connection
  • Send the user back through the authorization flow

How to prevent Confluence refresh token issues

Use this checklist to reduce “why did my Confluence API integration break?” tickets:

  • Store the replacement refresh token every time
    With rotating refresh tokens, the previous refresh token becomes invalid after use.
  • Single-flight refresh + atomic writes
    Lock refresh per connection and persist the full token set together, in one update.
  • Plan for inactivity expiry
    If a customer doesn’t use your Confluence integration for long periods, plan for an eventual reconnect.
  • Clear reconnect UX
    A fast “Reconnect Confluence” flow reduces support load and avoids retry storms.

Skip the headache, let Nango refresh for you

Nango's open-source API auth offers:

  • 600+ pre-built OAuth flows, including full support for all Confluence APIs
  • Automatic OAuth access token refreshing and rotation
  • Webhooks when a refresh token is revoked, so you can warn the user instantly
  • Built-in error handling for all OAuth edge cases

If you're building a Confluence API integration and you don’t want to maintain Atlassian OAuth edge cases (rotating refresh tokens, cloudid routing, and revocation handling), Nango can run the refresh pipeline for you.

Focus on product features, and let Nango handle the token lifecycle.

Oliver Anyanwu
Developer Relations

Stay in the loop

Bi-weekly tips, learnings & guides for product integrations

Join 5,000+ engineers, eng leaders & product managers
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.