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
- 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?
- Does B2C regenerate a new OTP when it detects session inconsistency, thereby invalidating the original email link's code?
- Is there a way to configure B2C custom policies to be more resilient to missing parent domain cookies?
- Are there any known issues with B2C session handling when traffic goes through different network paths (with/without corporate proxy)?
- 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.