Custom Entra ID auth on Static Web Apps: callback returns 401 with no Set-Cookie (token exchange fails)

Beatriz 20 Reputation points
2026-07-31T15:08:22.2433333+00:00

Azure Static Web Apps, Standard plan, deployed via the official GitHub Actions workflow (app_location: "/", api_location: "", output_location: ""). Static HTML app, no build step, no API.

PROBLEM

Custom Microsoft Entra ID authentication never creates a session. The pre-configured (built-in) Entra provider works correctly on the same resource, so session infrastructure and routing are functional.

Observed flow with custom registration:

  1. GET /.auth/login/aad
  2. Redirect to login.microsoftonline.com -> returns 200 OK (user authenticates successfully, consent screen appears)
  3. POST /.auth/login/aad/callback -> 401 Unauthorized
    • No Set-Cookie header in the response
    • Content-Type: text/html, empty body
  4. GET /.auth/me -> {"clientPrincipal": null}

With responseOverrides configured for 401, this manifests as an infinite login loop (callback returns 302 to /.auth/login/aad). Removing responseOverrides exposes the underlying 401.

The absence of Set-Cookie suggests the authorization code / token exchange is failing server-side, before any session is established.

CONFIGURATION

Minimal staticwebapp.config.json used for testing (no routes, no responseOverrides, no navigationFallback):

{

"auth": {

"identityProviders": {

  "azureActiveDirectory": {

    "registration": {

      "openIdIssuer": "https://login.microsoftonline.com/
Microsoft Security | Microsoft Entra | Microsoft Entra ID
0 comments No comments

Answer accepted by question author
Allan Solomon Mejia 8,500 Reputation points
2026-07-31T18:28:58.23+00:00

Thank you for providing the additional details, they're very helpful.

Since:

  • Entra ID authentication completes successfully (HTTP 200)
  • The authorization request reaches Microsoft Entra and the user authenticates successfully
  • The built-in Entra provider works on the same Static Web App
  • /.auth/login/aad/callback returns 401 before issuing the authentication cookie
  • /.auth/me returns "clientPrincipal": null

this indicates the failure is likely occurring during the authorization code/token exchange performed by the Static Web Apps authentication service, rather than within Microsoft Entra ID itself.

A few thoughts:

  • The Free Trial subscription should not prevent custom identity providers. Custom authentication is a feature of the Standard Static Web Apps plan, not the Azure subscription type itself. Since you've confirmed the app is running on Standard SKU, the trial subscription should not be the limiting factor.
  • Unfortunately, there is no documented mechanism to enable verbose diagnostics for the managed /.auth endpoints. The authentication middleware is platform-managed, and Application Insights does not expose its internal token exchange or validation steps.
  • Given that the built-in provider succeeds while the custom provider fails using the same tenant, this may indicate either:
    • a platform regression affecting the custom azureActiveDirectory provider, or
    • an issue with the authentication service handling the custom provider configuration.

At this point, I'd recommend opening an Azure Support request and including:

  • The Static Web App resource ID
  • Subscription ID
  • Region
  • Timestamp (UTC) of a failed login
  • The x-ms-request-id, x-ms-correlation-request-id, or any similar response headers from the failed POST /.auth/login/aad/callback
  • Your staticwebapp.config.json (with the client secret removed)

Those details allow the Azure Static Web Apps team to inspect the backend authentication logs, which aren't exposed to customers.

One additional question: Does this behavior reproduce in a brand-new Standard Static Web App with a minimal staticwebapp.config.json and a newly created Entra app registration? If it does, that would further point to a platform-side issue rather than a configuration problem.

This additional information should help determine whether this is an environmental configuration issue or something the Azure Static Web Apps engineering team needs to investigate.

Please "Accept the Answer" if this information helped you. This will help us and others in the community as well.Thank you for providing the additional details—they're very helpful.

Since:

  • Entra ID authentication completes successfully (HTTP 200)
  • The authorization request reaches Microsoft Entra and the user authenticates successfully
  • The built-in Entra provider works on the same Static Web App
  • /.auth/login/aad/callback returns 401 before issuing the authentication cookie
  • /.auth/me returns "clientPrincipal": null

this indicates the failure is likely occurring during the authorization code/token exchange performed by the Static Web Apps authentication service, rather than within Microsoft Entra ID itself.

A few thoughts:

  • The Free Trial subscription should not prevent custom identity providers. Custom authentication is a feature of the Standard Static Web Apps plan, not the Azure subscription type itself. Since you've confirmed the app is running on Standard SKU, the trial subscription should not be the limiting factor.
  • Unfortunately, there is no documented mechanism to enable verbose diagnostics for the managed /.auth endpoints. The authentication middleware is platform-managed, and Application Insights does not expose its internal token exchange or validation steps.
  • Given that the built-in provider succeeds while the custom provider fails using the same tenant, this may indicate either:
    • a platform regression affecting the custom azureActiveDirectory provider, or
    • an issue with the authentication service handling the custom provider configuration.

At this point, I'd recommend opening an Azure Support request and including:

  • The Static Web App resource ID
  • Subscription ID
  • Region
  • Timestamp (UTC) of a failed login
  • The x-ms-request-id, x-ms-correlation-request-id, or any similar response headers from the failed POST /.auth/login/aad/callback
  • Your staticwebapp.config.json (with the client secret removed)

Those details allow the Azure Static Web Apps team to inspect the backend authentication logs, which aren't exposed to customers.

One additional question: Does this behavior reproduce in a brand-new Standard Static Web App with a minimal staticwebapp.config.json and a newly created Entra app registration? If it does, that would further point to a platform-side issue rather than a configuration problem.

This additional information should help determine whether this is an environmental configuration issue or something the Azure Static Web Apps engineering team needs to investigate.

Please "Accept the Answer" if this information helped you. This will help us and others in the community as well.

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

3 additional answers

Sort by: Newest
  1. Beatriz 20 Reputation points
    2026-08-06T13:45:10.3866667+00:00

    Hello @Allan Solomon Mejia

    Thanks, this is helpful, and it confirms what the evidence pointed to.

    To answer your question: yes, the behavior reproduces in a brand-new Standard Static Web App with a newly created Entra app registration and a minimal staticwebapp.config.json (auth block only, no routes, no responseOverrides).

    I did this three times across three separate resources, each with a freshly created app registration and a new client secret. Identical result every time: the built-in provider works, the custom provider returns 401 at the callback with no Set-Cookie.

    Two practical notes:

    1. This subscription does not include technical support, so I have no path to submit an Azure Support request. Is there any way to escalate this to the Static Web Apps team from the Q&A side, given that the backend authentication logs are the only remaining place the root cause could be identified?
    2. The resources where the failure was captured have since been deleted during troubleshooting, so I no longer have a valid correlation ID pointing to a live resource. If it would be useful, I'm happy to spin up a disposable Standard Static Web App, reproduce the failure, and provide the resource ID, subscription ID, region, UTC timestamp and x-ms-middleware-request-id from the failed callback, just let me know if someone will be able to look at the backend logs, so the repro environment doesn't go to waste.

    In the meantime I've moved forward using the built-in Entra provider with role-based invitations, which meets our access-control requirement. So this is no longer blocking us but it would be good to know whether this is a known platform regression, since it would affect anyone trying to restrict a Static Web App to a single tenant.

    Was this answer helpful?

    0 comments No comments

  2. Beatriz 20 Reputation points
    2026-07-31T18:05:25.89+00:00

    Hello @Allan Solomon Mejia

    Thanks for your help. To answer your questions directly:

    1. ERROR MESSAGE: There is no AADSTS code anywhere in the flow. Entra authentication itself succeeds (POST to login.microsoftonline.com returns 200 OK, the consent screen renders, the user authenticates). The failure is entirely on the Static Web Apps side: POST /.auth/login/aad/callback returns 401 Unauthorized with no Set-Cookie header, Content-Type text/html, empty body. No error code, no diagnostic output. /.auth/me then returns {"clientPrincipal": null}.
    2. PROVIDER: Custom registration via staticwebapp.config.json (azureActiveDirectory identity provider). Notably, the BUILT-IN Entra provider works correctly on the same resource, login completes and clientPrincipal is populated. Only the custom registration fails.
    3. DOMAIN: Default *.azurestaticapps.net domain. No custom domain, no Front Door, no reverse proxy. Regarding your checklist, all four points were verified before posting:
    • Redirect URI matches character-for-character (verified against the URL bar; registered as platform type "Web", not SPA)
    • openIdIssuer tested with and without the /v2.0 suffix
    • clientIdSettingName and clientSecretSettingName reference application settings that exist in the Production environment (verified; the client_id in the /authorize request matches the registration)
    • Standard SKU confirmed on all three resources tested
    • The minimal config used for testing has no routes and no responseOverrides at all, so nothing is blocking /.auth/*

    Given that the callback returns a bare 401 with no Set-Cookie, the authorization code / token exchange appears to be failing server-side. Is there any way to surface the underlying error from the Static Web Apps auth handler? Application Insights, diagnostic logs, anything?

    Note: this is a Free Trial subscription, could that impose an undocumented limitation on custom authentication providers?

    Was this answer helpful?

    0 comments No comments

  3. Allan Solomon Mejia 8,500 Reputation points
    2026-07-31T17:58:30.9366667+00:00

    Hello @Beatriz

    If you're using custom Microsoft Entra ID authentication with Azure Static Web Apps, the callback (redirect URI) must match the callback endpoint that Static Web Apps exposes. The callback endpoint is handled by the platform—you don't implement it yourself.

    1. For Microsoft Entra ID, verify the following:
    • The redirect URI configured in your Entra app registration is exactly:
      • https://<your-app>.azurestaticapps.net/.auth/login/aad/callback or, if you're using a custom domain: https://<your-domain>/.auth/login/aad/callback

    The URI must match character-for-character, including the scheme (HTTPS), hostname, and path.

    1. If you're using a custom identity provider (staticwebapp.config.json), ensure:
    • openIdIssuer points to the correct tenant (https://login.microsoftonline.com/<tenant-id>/v2.0 for the v2 endpoint).
    • clientIdSettingName and clientSecretSettingName reference valid application settings.
    • Your app is running on the Standard SKU, as custom authentication isn't available on the Free plan.
    1. Confirm that no route rules or reverse proxy configuration are blocking the /.auth/* endpoints. Static Web Apps uses these endpoints internally to complete the authentication flow.

    If you're still experiencing callback or redirect issues, could you share:

    • The exact error message (for example, AADSTS50011 or another AADSTS code).
    • Whether you're using the built-in Entra ID provider or a custom OpenID Connect provider.
    • Whether the issue occurs on the default *.azurestaticapps.net domain, a custom domain, or both.

    That information will help narrow down whether the issue is related to the Entra app registration, the Static Web Apps configuration, or the redirect URI itself.

    Please "Accept the Answer" if this information helped you. This will help us and others in the community as well.

    Was this answer helpful?

    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.