# Auth0 Is returning invalid Refresh tokens

**URL:** <https://community.auth0.com/t/auth0-is-returning-invalid-refresh-tokens/190563>\
**Category:** Get Help\
**Tags:** classic-universal-login-experience, free-trial, login-experience\
**Created:** [August 13, 2025, 11:41am UTC](https://community.auth0.com/t/auth0-is-returning-invalid-refresh-tokens/190563 "2025-08-13T11:41:17Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![yahyashareef](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/yahyashareef/32/60286_2.png) [@yahyashareef](https://community.auth0.com/u/yahyashareef)\
**Post date:** [August 13, 2025, 11:41am UTC](https://community.auth0.com/t/auth0-is-returning-invalid-refresh-tokens/190563/1 "2025-08-13T11:41:17Z")

</div>

I am fetching a refresh token for a user from Auth0, but when I use the refresh token to refresh the ID and access token, I am getting this error.

```auto
{
  "error": "invalid_grant",
  "error_description": "Unknown or invalid refresh token."
}

```

Token exchange request:

```auto
const data = new URLSearchParams({
  grant_type: 'client_credentials',
  code: dto.code,
  client_id: process.env.OAUTH_CLIENT_ID || '',
  redirect_uri: dto.redirect_uri,
  scope: 'openid profile email offline_access',
});

```

Refresh token request:

```auto
const data = new URLSearchParams({
  grant_type: 'refresh_token',
  refresh_token: dto.refresh_token,
  client_id: process.env.OAUTH_CLIENT_ID || '',
  client_secret: process.env.OAUTH_CLIENT_SECRET || '',
  scope: 'openid profile email offline_access',
});

```

---

<div class="post-metadata">

**Author:** ![vlad.murarasu](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/vlad.murarasu/32/72793_2.png) [@vlad.murarasu](https://community.auth0.com/u/vlad.murarasu)\
**Post date:** [August 13, 2025, 1:32pm UTC](https://community.auth0.com/t/auth0-is-returning-invalid-refresh-tokens/190563/3 "2025-08-13T13:32:27Z")

</div>

Hi @yahyashareef,

The `client_credentials` grant type is designed for machine-to-machine communication and **does not issue refresh tokens**. To get a refresh token for a user, you must use a grant type that involves user authentication, such as the `authorization_code` grant.

Have a good one,  
Vlad

---

<div class="post-metadata">

**Author:** ![yahyashareef](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/yahyashareef/32/60286_2.png) [@yahyashareef](https://community.auth0.com/u/yahyashareef)\
**Post date:** [August 14, 2025, 3:58am UTC](https://community.auth0.com/t/auth0-is-returning-invalid-refresh-tokens/190563/4 "2025-08-14T03:58:14Z")

</div>

> [@vlad.murarasu](#):
>
> -machine communication

I am using the authentication\_code but still having the same error

```auto
    const data = new URLSearchParams({
      grant_type: 'authorization_code',
      code: dto.code,
      client_id: process.env.OAUTH_CLIENT_ID || '',
      redirect_uri: dto.redirect_uri,
      scope: 'openid profile email offline_access',
    });

```

Still returning `Unknown or invalid refresh token.`

---

<div class="post-metadata">

**Author:** ![vlad.murarasu](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/vlad.murarasu/32/72793_2.png) [@vlad.murarasu](https://community.auth0.com/u/vlad.murarasu)\
**Post date:** [August 18, 2025, 1:34pm UTC](https://community.auth0.com/t/auth0-is-returning-invalid-refresh-tokens/190563/5 "2025-08-18T13:34:12Z")

</div>

Hi again @yahyashareef,

The error `Unknown or invalid refresh token` indicates an issue with the refresh token itself or the configuration of your application and API in Auth0. It commonly occurs if offline access isn’t enabled for your API, if you’re re-using a rotated token, or if the token wasn’t issued correctly in the first place.

`authorization_code` is the right grant for user-centric flows. The error you’re seeing now happens during the second step: when your application tries to exchange the refresh token for a new access token.

This points to a few very likely causes:

1. **Offline Access Not Enabled:** Your API (the “Audience” for the token) must be explicitly configured in the Auth0 Dashboard to allow the issuance of refresh tokens.

2. **Refresh Token Rotation:** If token rotation is enabled on your application, each time you use a refresh token, it is invalidated and a _new_ one is issued. If your code attempts to use the old token again, it will fail with this exact error.

3. **Missing Client Secret (for Confidential Apps):** If your application is a “Regular Web Application,” it’s considered a confidential client and **must** provide its `client_secret` during the initial `authorization_code` exchange. Your code snippet for that exchange is missing it, which could mean a valid refresh token was never issued.

I recommend you generate a completely new authorization code and token set after checking the following settings.

#### 1. Enable “Allow Offline Access” for Your API

This is the most frequent cause of this issue.

- Go to your [Auth0 Dashboard](https://manage.auth0.com/).
- In the left sidebar, navigate to **Applications \> APIs**.
- Select the API you are using as the audience for your tokens.
- Click the **Settings** tab.
- Scroll down to the “Access Settings” section and **enable the “Allow Offline Access” toggle**.
- Click **Save**.

#### 2. Handle Refresh Token Rotation

Check if rotation is active and ensure your code handles it correctly.

- In the dashboard, navigate to **Applications \> Applications**.
- Select the application you are using.
- Under the **Settings** tab, scroll down to **Refresh Token Behavior**.
- If **Rotation** is enabled, you **must** capture and save the _new_ refresh token that is returned in the body of a successful refresh token exchange. The old one is now invalid.

#### 3. Add the Client Secret to the Token Exchange

If your application is a **Regular Web App** , the `client_secret` is required to prove its identity when exchanging the code for tokens.

Your `authorization_code` grant request should look like this:

```javascript
const data = new URLSearchParams({
  grant_type: 'authorization_code',
  code: dto.code,
  client_id: process.env.OAUTH_CLIENT_ID || '',
  client_secret: process.env.OAUTH_CLIENT_SECRET || '', // <-- Ensure this is included
  redirect_uri: dto.redirect_uri,
});

```

The `scope` parameter is generally not needed in the `/oauth/token` request, as the scopes were already determined in the initial `/authorize` call that generated the `code`.

If you have any further questions feel free to reach out!

Have a good one,  
Vlad

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/auth0/original/3X/b/5/b560f266932fcce5d57f09a6595bd50518cae3f3.jpeg) [@system](https://community.auth0.com/u/system)\
**Post date:** [September 1, 2025, 1:34pm UTC](https://community.auth0.com/t/auth0-is-returning-invalid-refresh-tokens/190563/6 "2025-09-01T13:34:42Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
