Setup
-
Angular SPA, auth0-spa-js v1.13.6, New Universal Login
-
Custom domain with OIDC proxy behind it
-
initiate_login_uri set to <APP_URL>/login
The problem
After logout + re-login immediately:
-
User submits credentials on the Auth0 login form
-
Instead of redirecting back to the app with ?code=&state=, the browser receives:
<APP_URL>/?iss=https://<CUSTOM_DOMAIN>/
-
Angular app loads, LoginComponent fires loginWithRedirect() again
-
The Auth0 login form re-renders — user has to log in a second time
-
On the second attempt it usually succeeds and lands on /policies
However — if the user waits a few minutes after logout and then tries to login, the issue does not occur. Login completes in one attempt as expected.
This never happens with the standard tenant domain (xxx.eu.auth0.com) regardless of timing.
What we have tried — none fully resolved it
-
Removed / blanked initiate_login_uri → no effect
-
prompt: 'login' + max_age: 0 on loginWithRedirect() → reduces frequency, not eliminated
-
federated: true on logout() → helps but issue still occurs immediately after logout
-
Passing iss back in subsequent loginWithRedirect() → intermittent improvement
-
Clearing browser cookies for custom domain → fixes it temporarily
Key observations
-
Issue is timing dependent — happens immediately after logout, not after a wait. Suggests a stale session or token in the OIDC proxy that takes time to expire/clear
-
?iss= lands on app root (/?iss=), not /login?iss= — suggests the OIDC proxy behind the custom domain generates it, not Auth0’s initiate_login_uri
-
prompt=login does not suppress the ?iss= redirect — proxy appears to ignore it
-
Opening the login URL in a second browser window during an active login reliably triggers the issue
Questions
-
Is the ?iss= redirect caused by a stale session in the OIDC proxy not yet cleared after federated: true logout?
-
Why does this only happen with the custom domain and not the standard tenant domain?
-
Is the OIDC proxy behind the custom domain responsible for generating ?iss=, not Auth0 itself?
-
Is there a way to force the proxy session to clear immediately on logout rather than waiting for natural expiry?
-
Does upgrading to auth0-spa-js v2.x resolve this?
Hi @aravind.ps
The double-login issue you are experiencing appears to be the result of Auth0 falling back to an IdP-Initiated Login flow (indicated by the ?iss= parameter you mentioned). This happens because a race condition with first-party cookies on your custom domain causes Auth0 to lose the context of your application’s initial /authorize transaction.
When Auth0 successfully verifies the user’s credentials but cannot find the matching OAuth2 transaction state to securely redirect them back to the app, it triggers the fallback IdP-Initiated flow, which your Angular app then intercepts and restarts.
→ The issue appears to be caused when you call loginWithRedirect(), causing your Angular app generates a state parameter and redirects the browser to Auth0’s /authorize endpoint. Auth0 sets a transaction cookie (e.g., auth0.tx ) in the browser to remember where to send the user back after they type their password. When using a custom domain (e.g., auth.yourdomain.com ), Auth0’s cookies are treated as first-party cookies by the browser, just like your app’s cookies.
→ When a user logs out (/v2/logout ), Auth0 instructs the browser to expire the session and transaction cookies. If the user immediately logs back in, the browser may not have finished clearing the old first-party transaction cookies before the new /authorize request fires.
→ Auth0 receives the /authorize request mixed with stale transaction cookies. It gets confused, processes the user’s credentials successfully, but discards the corrupted transaction state.
→ Because Auth0 lost the redirect_uri and state from step 1, it doesn’t know how to complete the standard OAuth2 flow. Instead, it falls back to the OIDC standard for “IdP-Initiated Login.” Auth0 redirects the user back to the application and appends ?iss=https://<CUSTOM_DOMAIN>/ to tell the app to restart the authentication process.
To answer your questions:
- No, it is caused by stale transaction cookies in the user’s browser, not the upstream proxy session. Auth0’s backend misreads the state due to the rapid sequence of cookie deletion and creation.
- Browsers isolate and process third-party cookies (
tenant.eu.auth0.com ) differently than first-party custom domain cookies. The standard domain avoids this race condition because the third-party cookie storage partitions clear and write without overlapping with your application’s immediate network requests.
- Auth0 is generating the
?iss= parameter. It is the standard OIDC mechanism Auth0 uses to signal an IdP-Initiated login when the standard transaction state is lost.
Note on the root URL: You mentioned it redirects to your root /?iss= instead of /login . This is because Auth0 uses the Default Login Route field in your Application Settings for this fallback redirect. If that field is blank, Auth0 defaults to the first Allowed Callback URL or the root of your app, ignoring the OIDC initiate_login_uri.
- SOLUTION: The fix lies in giving the browser time to clear the cookies, rather than forcing the proxy.
- Ensure your logout call points to Auth0’s
/v2/logout endpoint with both client_id and returnTo parameters to guarantee local Auth0 cookies are explicitly expired.
- Workaround: Implement a tiny, intentional delay (e.g., 500ms to 1000ms) in your Angular app’s UI after a logout completes before rendering the login button or allowing a re-login. This gives the browser the necessary tick to finalize the cookie destruction.
- Yes, it is highly likely to resolve this. Version 2.x of the SDK introduced significant overhauls to how transactions are stored and handled, specifically moving away from legacy cookie fallbacks and optimizing for modern browser storage partitioning. Upgrading is the strongest architectural fix for custom domain stability.
If you have any other questions, let me know!
Kind Regards,
Nik