Share via

Azure AD B2C Custom Policy - Email OTP verification fails after ~2-3 minutes despite 20-minute expiration configured - Session cookies lost without VPN

Sven Goormans 0 Reputation points
2026-02-13T13:16:55.82+00:00

Users attempting to sign up using a magic link (email OTP verification) in Azure AD B2C receive an "Invalid verification code" error after approximately 2-3 minutes, even though the OTP expiration is configured for 20 minutes (1200 seconds). The issue ONLY occurs when users are NOT connected to corporate VPN.

Environment

  • B2C Tenant: [TENANT_NAME].onmicrosoft.com
  • Affected Website: www.[CUSTOMER_SITE].com
  • Custom Policy: B2C_1A_SIGNUP (Identity Experience Framework)
  • Login Domain: login.[COMPANY_DOMAIN].com
  • Azure Front Door: [FRONTDOOR_NAME]
  • Hosting: Optimizely DXP (Azure App Service)

Error Message

  • Error Code: UserMessageIfInvalidCode
  • Message: "The verification code is invalid. Please try again."

  


  

  

Root Cause Evidence - Cookie Analysis

We captured browser cookies in both scenarios and found a critical difference:

✅ Working (VPN enabled**) - 18 cookies:**

  • 14 .[COMPANY_DOMAIN].com parent domain cookies present
  • 5 .login.[COMPANY_DOMAIN].com B2C session cookies
  • x-ms-cpim-trans shows 2 transaction records (session continuity maintained)

❌ Not Working (No VPN) - Only 4 cookies:

  • ZERO .[COMPANY_DOMAIN].com parent domain cookies
  • Only 4 .login.[COMPANY_DOMAIN].com B2C cookies
  • x-ms-cpim-trans shows only 1 transaction record (session context lost)

Decoded x-ms-cpim-trans Cookie Comparison

Working:

{"T_DIC":[
  {"P":"b2c_1a_signup_signin","S":1},
  {"P":"b2c_1a_signup","S":3}
],"C_ID":"[GUID-1]"}


Not Working:

{"T_DIC":[
  {"P":"b2c_1a_signup","S":8}
],"C_ID":"[GUID-2]"}


The missing transaction history indicates session state is being lost.

Audit Log Evidence

B2C Audit logs show this pattern when it fails:

T+0:00 - Generate OTP: ✅ Success

T+2:34 - Verify OTP: ❌ "Session has expired"

T+5:45 - Verify OTP: ❌ "Code incorrect" (new session, old code invalid)

What We've Already Verified

  • ✅ All B2C custom policies have correct OTP expiration (1200 sec)
  • ✅ All B2C custom policies have correct session expiration (28800 sec)
  • ✅ No 2-minute timeout in TrustFrameworkBase, Extensions, or policy files
  • ✅ Application code (ASP.NET Core) has no 2-minute timeout
  • ✅ Azure Front Door configuration reviewed

Questions for Support

  1. Why does Azure AD B2C treat the session as "expired" when parent domain cookies are missing, even though B2C's own session cookies (.login.*) are present?
  2. Does B2C regenerate a new OTP when it detects session inconsistency, thereby invalidating the original email link's code?
  3. Is there a way to configure B2C custom policies to be more resilient to missing parent domain cookies?
  4. Are there any known issues with B2C session handling when traffic goes through different network paths (with/without corporate proxy)?
  5. Can B2C be configured to validate OTP based solely on the code value without requiring full session cookie continuity?
**Relevant Microsoft Documentation:**
- https://learn.microsoft.com/en-us/azure/active-directory-b2c/cookie-definitions
- https://learn.microsoft.com/en-us/azure/active-directory-b2c/session-behavior

The session-behavior doc states: "If the user uses a browser that blocks 
third-party cookies, there are limitations with SSO due to limited access 
to the cookie-based session."

Our evidence suggests cookies are being lost/stripped when traffic does 
NOT go through VPN, causing the B2C session to become invalid.
Microsoft Security | Microsoft Entra | Microsoft Entra ID
{count} votes

2 answers

Sort by: Most helpful
  1. Sven Goormans 0 Reputation points
    2026-02-18T13:57:25.06+00:00

    @kagiyama yutaka we've investigated our cloudflare instance, but we're not seeing any errors related to aadb2c.

    Any other ideas are welcome! :-)

    0 comments No comments

  2. kagiyama yutaka 1,165 Reputation points
    2026-02-13T22:30:08.3233333+00:00

    might be wrong here, but that 2–3 min timeout off‑VPN really looks like AFD hopping nodes and dropping the B2C session cookies on the redirect. pin it to one AFD path (no cache/WAF, sticky on) and see and every time I’ve hit this, the OTP suddenly lasts the full 20 mins.

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.