Troubleshooting Guide
| Symptom | Likely cause | Resolution |
|---|---|---|
| AADSTS50020 — "user account … does not exist in tenant" | App 1 is still single-tenant, or the SPA authority is pinned to one tenant | Set App 1 to Multitenant; SPA authority …/organizations; API authority …/organizations/v2.0 |
| "Sign-in tenant not onboarded" (401) | The customer's tenant isn't in the registry yet | Complete Tenant Onboarding step 6 before that tenant's users try to sign in |
| "Missing permission '…' for tenant …" | The signed-in user's role doesn't grant that permission, or the assignment scope is wrong | Assign a role that grants it, scoped to the correct tenant, in Access Control |
Graph 403 Authorization_RequestDenied on a read | App 2 (Data) hasn't been admin-consented in that tenant, or is missing the scope | Grant admin consent to App 2 in the customer tenant; add the missing Graph permission |
Graph 403 on disable user / reset access | The action is a Graph "sensitive action" and needs a directory role, not just a permission | Assign User Administrator (disable/enable) or Authentication Administrator (reset access) to App 2's service principal in that tenant |
Graph 403 when disabling an admin account | The target user holds an admin directory role | This is by design — CET2 cannot disable admin accounts with this privilege level. Surfaced in the UI before the action is attempted, not left to fail at Graph |
| Step-up "Session too old" | The auth_time claim isn't fresh, or isn't present on the access token | Confirm the auth_time optional claim is added to App 1's access token; as an interim measure the destructive step-up window can be widened via Cet2:Actions:DestructiveMaxAgeMinutes; the durable fix is Conditional Access authentication context |
| 502 Bad Gateway on a page | The underlying Graph call failed — usually a missing permission or an unconfigured Intune feature | Check the specific Graph permission for that feature; a feature that simply isn't configured in the tenant (e.g. no Apple management) returns an empty result, not an error |
| SPA loads blank, or assets are blocked | A reverse-proxy Content-Security-Policy is blocking the app's own scripts/styles, or the redirect URI doesn't match exactly | Relax the CSP for the portal's own origin; register the exact portal URL (scheme + host, no trailing path) as a redirect URI |
| Backend won't start | The Graph certificate can't be resolved | Confirm the Managed Identity has Key Vault Secrets User on the vault (Azure hosting), or that the mounted PFX path/CertificateName is correct (self-hosted) |
| Frontend build fails | Wrong Node version, or a stale node_modules | Use Node 18+ and a clean npm ci |
| Startup cert guard error | Cet2:Actions:Enabled=true in production without certificate authentication configured | Switch to certificate authentication, or set the documented override deliberately if you understand the trade-off |
Still stuck?
Cross-check against the Validation Testing checklist — most failures map directly onto one of its numbered tests, which will tell you exactly which stage of the deployment to re-examine.