Determine if refresh token has expired

Hi auth0 team!

How can we determine if our stored credential’s refresh token has expired? I have found that getCredentials will throw the error RENEW_FAILED: An error occurred while trying to use the Refresh Token to renew the Credentials when the refresh token is expired; is that error specific to refresh token expiry?

We want to log and treat refresh token expiry separate to a legitimate error. From what I can tell the credentials expiresAt is for the access token, not the refresh token. If it helps this is a react native app using the react-native-auth0 sdk.

Thanks in advance :slight_smile:

Hi @clairel

I am sorry about the delayed response to your inquiry!

RENEW_FAILED is a generic catch-all error which is thrown by the react-native-auth0 SDK whenever the background attempt to get a new access token fails. This can happen if:

  • The refresh token is expired
  • It was manually revoked
  • Arotated token was reused
  • The user was deleted/blocked

As you have mentioned, the expiresAt property returned by getCredentials corresponds only to the short-lived Access Token, not the Refresh Token.

In order to separate a legitimate refresh token expiry from a transient error, you need to inspect the underlying payload of the error thrown by getCredentials.

When a refresh token is expired or revoked, the Auth0 server specifically returns an invalid_grant error, and the message usually containing the phrase "Unknown or invalid refresh token".

An example on handling these specific errors as you have mentioned above would be:

const fetchValidCredentials = async () => {
  try {
    const credentials = await getCredentials();
    return credentials;
  } catch (error) {
    if (error.code === 'RENEW_FAILED') {
      
      const errorMessage = error.message?.toLowerCase() || '';
      
      if (
        errorMessage.includes('invalid_grant') || 
        errorMessage.includes('unknown or invalid refresh token')
      ) {
        console.warn('Refresh token has explicitly expired or been revoked.');
        
        await clearCredentials();
        return null; 
      }
      
      console.error('Credential renewal failed for another reason:', error);
    }
    
    throw error;
  }

Please bare in mind that some of the errors above can also be thrown by your application if there is a misconfiguration or other underlying causes(race conditions when using Refresh Token Rotation, malicious replay attempts. reuse of refresh tokens etc.)

If you have any other questions, let me know!

Kind Regards,
Nik

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