How to Identify an Expired Refresh Token in the Auth0 React Native SDK
Last Updated:
Overview
Auth0 generates a generic RENEW_FAILED error in the React Native SDK when a background attempt to retrieve a new access token fails. This occurs because the refresh token expires, undergoes manual revocation, or experiences a rotation conflict, and the expiresAt property only applies to the short-lived access token. Inspect the underlying error payload for an invalid_grant code to identify an expired refresh token and clear the credentials to determine the reason of failure.
Applies To
- React Native SDK (
react-native-auth0) - Refresh Tokens
Cause
The error occurs because the RENEW_FAILED code acts as a generic catch-all for any background token renewal failure. The expiresAt property that the getCredentials method returns corresponds only to the short-lived access token, requiring developers to inspect the specific error payload to confirm if the refresh token expired or underwent revocation.
Solution
How is an expired refresh token identified using the React Native SDK?
To identify an expired refresh token and separate it from a transient error, inspect the error payload that the getCredentials method throws and clear the credentials by implementing the following code:
- Locate the authentication logic within the React Native application.
- Implement error handling around the
getCredentialsmethod to catch theRENEW_FAILEDerror code. - Inspect the error message for the
invalid_grantstring or the "Unknown or invalid refresh token" phrase, which Auth0 returns when a refresh token expires or undergoes revocation. - Execute the
clearCredentialsmethod to remove the invalid tokens and prompt the user to authenticate again. - Apply the following JavaScript code example to handle the specific refresh token errors.
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(); await authorize({ scope: 'openid profile offline_access' }); } console.error('Credential renewal failed for another reason:', error); } throw error; } }; - Save and deploy the updated application code.