checkSession returns login_required after a few successful calls when using Universal Login with a Custom Domain

Title: checkSession returns login_required after a few successful calls when using Universal Login with a Custom Domain

Hi everyone,

I’m facing an issue with auth0.checkSession() and would appreciate any guidance.

Setup:

  • Application Type: Machine-to-Machine (M2M)
  • Authentication: Universal Login
  • SDK: Auth0.js
  • Custom Domain: Enabled

Issue:

A user logs in successfully and the Auth0 session is maintained. After login, I call auth0.checkSession() approximately every 4 minutes to verify whether the user still has an active session.

Initially, checkSession() works as expected. However, after 2–3 successful checks, it starts failing with the following error:

login_required

This happens even though the user has not logged out and the session is expected to remain active.

Questions:

  1. What could cause checkSession() to start returning login_required after a few successful calls?
  2. Could this be related to session settings, browser behavior, or the use of a custom domain?
  3. Are there any recommended configurations or best practices to prevent this issue?

Any suggestions or troubleshooting steps would be greatly appreciated.

Thank you!

Hi @dhrupal.patel

Thank you for reaching out to us!

I understand that are calling auth0.checkSession() about every 4 minutes to verify if a user still has a session, but it fails after a couple of checks.

Please allow us some time to research this matter and we will return with guidance in a timely manner.

Best regards,
Gerald

Thank you @gerald.czifra .

Hi @dhrupal.patel

Thank you for your patience!

Generally speaking, the login_required error from checkSession() means that the Auth0 authorization server could not detect a valid session cookie within the hidden iframe it uses to silently renew tokens.

Before diving into the common culprits, there is a critical configuration detail to address in your setup: Machine-to-Machine (M2M) applications are not designed for interactive user sessions. M2M applications use the Client Credentials grant for backend API-to-API communication. Auth0.js, Universal Login, and checkSession() are meant for Single Page Applications (SPAs). If your application is registered as M2M in the Auth0 dashboard, you should create a new SPA application and use those credentials.

Potential causes why checkSession() might start failing after a few successful calls when using a Single Page Application:

1. Inactivity Timeout or Absolute Session Lifetime

Auth0 tenant settings define how long a session lives. If your tenant’s Inactivity Timeout (Require log in after X minutes) is reached, Auth0 destroys the session.

  • Even though you are calling checkSession() every 4 minutes, silent authentication requests do not automatically extend the inactivity window unless specifically configured to do so.

  • Once the absolute lifetime or inactivity threshold is hit, the cookie expires, and checkSession() correctly returns login_required.

2. Custom Domain Initialization Mismatch

While you have a Custom Domain enabled, you must ensure that your auth0.WebAuth instance is actually using it.

  • If your Auth0.js SDK is still initialized with your canonical domain (e.g., your-tenant.auth0.com) instead of your custom domain (e.g., login.yourdomain.com), the browser will treat the checkSession iframe request as cross-origin.

  • Modern browsers (especially Safari with ITP, or Chrome blocking third-party cookies) will eventually block the cookie in the iframe, causing the silent authentication to fail.

3. Using Auth0 Development Keys for Social Logins

If your users are logging in via a social connection (like Google or Facebook) and you are still using Auth0’s default development keys rather than providing your own Client ID and Secret in the Auth0 Dashboard, checkSession() will inherently fail and return login_required by design.

4. HTTP vs HTTPS Protocol Mismatches

If your app is hosted locally or behind a proxy that redirects HTTP to HTTPS, the iframe might be attempting to execute over HTTP while the cookies are marked as Secure (HTTPS only). This mismatch prevents the session cookie from being sent to Auth0.


Recommended Troubleshooting Steps & Best Practices

  1. Verify the App Type: Ensure your application is set up as a Single Page Application in the Auth0 Dashboard, not M2M.

  2. Check SDK Initialization: Confirm that your Auth0.js initialization uses your custom domain for the domain parameter, not the default Auth0 tenant URL:

    const webAuth = new auth0.WebAuth({
      domain: 'login.yourcustomdomain.com', // MUST be the custom domain
      clientID: 'YOUR_CLIENT_ID',
      // ...
    });
    
  3. Review Session Limits: Go to Auth0 Dashboard > Tenant Settings > Advanced. Check the " Idle Session Lifetime" settings to ensure they align with your expected session longevity.

  4. Configure Social Connections: If using social logins, ensure you have input your own keys in the Auth0 Dashboard under Authentication > Social.

  5. Check Browser Console & Network Tab: Open your developer tools, ensure “Preserve Log” is on, and watch the Network tab. Look for the iframe request to the /authorize?prompt=none... endpoint. Check if the Auth0 session cookie (auth0) is actually being attached to the Request Headers when the error occurs.

Hope this information helped troubleshoot and clear the issue on your end!

Have a great one,
Gerald