The 'offline_access' scope was requested, but no 'refresh_token' was issued..." Error Message After Deploying SPA

Problem statement

We experienced an error after deploying our SPA application:

The scope ‘offline_access’ was requested, but no ‘refresh_token’ was issued because the authorization code exchange originated from a browser .”

Symptoms

Repeated instances of this message appear in the tenant logs:

The scope ‘offline_access’ was requested, but no ‘refresh_token’ was issued because the authorization code exchange originated from a browser.”

  • These errors are typically associated with a specific application.
  • If more than one application has been misconfigured, these messages may be associated with two or more applications.

Steps to reproduce

Enable the non-rotating refresh token for an application and try to make a code exchange with /oauth/token endpoint while sending the Origin header.

Troubleshooting

  • Check the tenant logs for instances of the error:

The scope ‘offline_access’ was requested, but no ‘refresh_token’ was issued because the authorization code exchange originated from a browser.”

  • Check the application settings to see if the non-rotating refresh token is enabled for an SPA-type application.

Cause

Non-rotating refresh tokens are considered more sensitive compared to rotating refresh tokens. It is recommended to use rotating refresh tokens instead of non-rotating refresh tokens for SPA and Mobile type applications.

When the non-rotating refresh token is enabled for the application, and if the client sends the Origin header for code exchange request with POST /oauth/token call, Auth0, by default, prevents issuing tokens and throws this error.

Solution

Auth0 recommends using rotational refresh tokens from browsers. The default setup doesn’t allow the use of non-rotating refresh tokens from browsers. If non-rotating refresh tokens must be used from the browsers, please open a support ticket with Auth0.

For applications that perform the token exchange outside browsers and need non-rotating refresh tokens, ensure the Origin header isn’t sent with POST /oauth/token call.

If a self-managed custom domain is configured on the tenant, removing the Origin header following these steps on the custom domain proxy may also be possible.

  1. Filter requests with client_id=APP_CLIENT_ID and grant_type=authorization_code for POST /oauth/token calls
  2. Remove the Origin header for the matching requests.