# Bram Brinkmeier: Entra ID sign-in errors, read for security (full text) Generated 2026-11-08T15:15:25.046Z. 118 AADSTS code pages, 35 of them lab-reproduced. Each page below starts after a separator line and names its canonical URL; the same text is available per code at https://brambrinkmeier.com/entra/aadsts/.md and as JSON at https://brambrinkmeier.com/api/aadsts/.json. Index: https://brambrinkmeier.com/api/aadsts/index.json. What the files contain and how they are made: https://brambrinkmeier.com/for-agents/. License: CC BY 4.0 for the author's own text; quoted Microsoft wording belongs to Microsoft. Attribution: Bram Brinkmeier, https://brambrinkmeier.com/. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/16000/ # AADSTS16000: Account isn't in the tenant the app uses (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/16000/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/16000.json **Short answer:** AADSTS16000 means a user signed in with an account that doesn't exist in the tenant the app sent them to, so it can't use that app there. Usually it's a personal Microsoft account, the wrong account in the browser, or an external user who was never added as a guest. It has low attack value. The fix is to sign in with the right account or invite the user. **Fix:** User: sign out or open a private window, then sign in with your work account. From another organisation? Ask the app owner to invite you as a guest. Admin: invite the external user as a guest (B2B). Developer: use `/organizations` or `/common` if the app should accept other organisations. | Field | Value | |---|---| | Code | AADSTS16000 | | Microsoft name | InteractionRequired | | Category | Guests and tenants | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS16000 mean? Microsoft's description: > **InteractionRequired**: User account '{EmailHidden}' from identity provider '{idp}' doesn't exist in tenant '{tenant}' and can't access the application '{appid}'({appName}) in that tenant. This account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Microsoft Entra user account. This error is fairly common when you try to sign in to Microsoft Entra admin center by using personal Microsoft Account and no directory associated with it. The user proved who they are at their own identity provider. The tenant the app sent them to has no user or guest object for that account, so the sign-in stops there. The wording is almost the same as [50020](https://brambrinkmeier.com/entra/aadsts/50020/). Microsoft doesn't document when Entra returns 16000 and when it returns 50020. Our reading: the name `InteractionRequired` suggests 16000 is the variant returned when the user can fix it by signing in again with another account. Treat the causes and fixes of the two codes as the same. ## Is it an attack? No, in almost all cases. Microsoft's description names the most common cause itself: a personal Microsoft account used on the Entra admin center. Microsoft's 50020 troubleshooting article explains that case: *"you are connected to the Microsoft Services tenant by default. Within the default tenant, there is no linked directory for performing any actions. This behavior is expected."* | Pattern | Likely meaning | |---|---| | A personal account (outlook.com, hotmail.com) on an Azure or Entra portal | The user picked the wrong account, or has no directory of their own. Benign. | | A partner user on one specific app, repeating | The partner was never invited as a guest, or the guest object was deleted. | | One user who has both a work and a personal account | The browser silently reused the wrong session. Benign. | | Many users from one other company on one app | The app sends everyone to your tenant (a tenant-specific authority) but expects outside users. App or invitation problem. | There is no documented attack pattern for 16000. The account has already authenticated at its home, and your tenant refuses it. As far as we can tell, an attacker gains nothing from this error that they didn't already have. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 16000 is logged in. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "16000" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Which apps and which home tenants are involved. `HomeTenantId` is documented as *"the tenant identifier of the user initiating the sign in"*, so it tells you which organisation the outside users come from: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "16000" | summarize Rows = count(), Users = dcount(UserPrincipalName), Sample = make_set(UserPrincipalName, 10) by AppDisplayName, AppId, HomeTenantId, ResourceTenantId | sort by Users desc ``` We haven't checked this against real data, but the user name may be hidden or empty in these rows, because Microsoft's message template shows `{EmailHidden}`. If `UserPrincipalName` is empty, look at `SignInIdentifier`. Users who keep failing with 16000 on the same app and never succeed afterwards. These are the ones that need an invitation or an app change, not a retry: ```kusto let fails = SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "16000" | summarize Fails = count(), LastFail = max(TimeGenerated) by UserPrincipalName, AppId, AppDisplayName; let successes = SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "0" | summarize LastSuccess = max(TimeGenerated) by UserPrincipalName, AppId; fails | join kind=leftouter successes on UserPrincipalName, AppId | where isnull(LastSuccess) or LastSuccess < LastFail | where Fails >= 3 | project UserPrincipalName, AppDisplayName, Fails, LastFail | sort by Fails desc ``` The threshold of 3 is a starting point. If the first query shows most rows in `AADNonInteractiveUserSignInLogs`, run the others against that table too. Non-interactive rows are aggregated when application, user, IP address, status and resource ID match, so row counts there are not request counts. ## How do I fix AADSTS16000? **For the user:** sign out, or open a private browser window, and sign in again with your work account. Microsoft's description says to *"sign in again with a different Microsoft Entra user account"*. If you used a personal Microsoft account on the Azure or Entra portal and you have no directory of your own, you need to create one; Microsoft's 50020 article says *"If you aim to have a directory, you must create an Azure account and a new tenant."* If you are from another organisation, ask the app owner to invite you as a guest. **For developers:** check which authority your app uses. Microsoft's 50020 article says that with `https://login.microsoftonline.com/` *"users from other organizations can't access the application. You have to add these users as guests in the tenant that's specified in the request."* If the app is meant for any organisation, use `/organizations` (or `/common` if personal accounts are allowed too), and make sure the app registration's supported account types allow it. **For admins:** 1. External user who needs access: invite them as a guest (B2B). Microsoft's description says the account *"needs to be added as an external user in the tenant first."* 2. Guest that used to work: check whether the guest object was deleted, or whether the home tenant re-created the account. For the second case Microsoft's 50020 article says to reset the guest's redemption status instead of deleting and re-inviting. 3. Give guests a tenant-specific link. Microsoft's redemption article: *"A direct link is tenant-specific. In other words, it includes a tenant ID or verified domain so the guest can be authenticated in your tenant."* 4. Many users from one partner on one app: decide whether that app should accept them at all. If yes, invite them, ideally as a group; if no, the error is doing its job. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Troubleshoot error AADSTS50020 (user account from identity provider does not exist in tenant)](https://learn.microsoft.com/en-us/troubleshoot/azure/entra/entra-id/app-integration/error-code-aadsts50020-user-account-identity-provider-does-not-exist) 3. [B2B collaboration invitation redemption](https://learn.microsoft.com/en-us/entra/external-id/redemption-experience) 4. [Troubleshoot Microsoft Entra B2B collaboration](https://learn.microsoft.com/en-us/entra/external-id/troubleshoot) 5. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/), [AADSTS90072](https://brambrinkmeier.com/entra/aadsts/90072/), [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS16000: Account isn't in the tenant the app uses (fix)", https://brambrinkmeier.com/entra/aadsts/16000/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50001/ # AADSTS50001 fix: resource disabled or doesn't exist Canonical: https://brambrinkmeier.com/entra/aadsts/50001/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50001.json **Short answer:** AADSTS50001 means an app asked Microsoft Entra ID for a token to a resource (an API) that is disabled or doesn't exist. Usually the resource URL in the app's code or settings is wrong. Users report it in Nintex, Power BI and custom web APIs. It is a configuration error with low attack value. 500011 is the related code for a resource with no service principal in the tenant. **Fix:** Developer: check that the resource URL in your code or app settings exactly matches the API's identifier. Admin: find the resource under Enterprise applications and check it exists in the tenant. If it is switched off, that case is documented as AADSTS500014. | Field | Value | |---|---| | Code | AADSTS50001 | | Microsoft name | InvalidResource | | Category | App configuration | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS50001 mean? Microsoft's description: > **InvalidResource**: The resource is disabled or doesn't exist. Check your app's code to ensure that you have specified the exact resource URL for the resource you're trying to access. The **resource** is the API the app wants a token for: Microsoft Graph, SharePoint, or your own web API. Entra ID couldn't use it, because the identifier in the request matches nothing usable, or the resource is switched off. Users post a message that names the resource and the tenant: *"AADSTS50001: The application named was not found in the tenant named ."* **50001 or 500011?** [500011](https://brambrinkmeier.com/entra/aadsts/500011/) is Microsoft's code for a resource with no service principal in the tenant: *"The resource principal named {name} wasn't found in the tenant named {tenant}."* The messages users post for the two look alike. Microsoft's 50001 description adds one cause that 500011 doesn't have: a resource that exists but is **disabled**. Our reading: check the resource URL first for either code. If the resource's service principal exists but is switched off (**Enabled for users to sign-in?** set to No), Microsoft documents that as [500014](https://brambrinkmeier.com/entra/aadsts/500014/), so look there first. If the missing object is the client app, not the resource, the code is [700016](https://brambrinkmeier.com/entra/aadsts/700016/). Our reading is that a disabled client app returns [7000112](https://brambrinkmeier.com/entra/aadsts/7000112/). ## Is it an attack? No. A request for a resource that doesn't exist gets nothing back. Users report it in integrations with a wrong or unexpected resource: - **Nintex for Office 365**: the error appeared when documents were stored on a SharePoint subsite. The reported fix was to store them at the site collection level. - **A custom web API used from Power BI / Azure**: the resource named in the error was the web service's own domain, which wasn't registered in the tenant. One reply suggested the custom domain setup; a later commenter said that didn't help. | Pattern | Likely meaning | |---|---| | One app, every user, starting at a deployment or settings change | A wrong resource URL or App ID URI in the app's settings. Developer error. | | An app that worked starts failing for everyone, with no code change | Something changed on the resource side. Check the resource's enterprise app and app registration; if it was switched off, Microsoft documents that case as [500014](https://brambrinkmeier.com/entra/aadsts/500014/). | | 50001 naming a resource you don't recognise, from an app or IP you don't recognise | Someone asking your tenant for tokens to an API you never set up. Not a documented detection, but worth a look. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 50001 lands in. Check your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "50001" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which client apps fail, and the resource they asked for: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "50001" | summarize Rows = count(), Resources = make_set(ResourceIdentity, 10), ResourceNames = make_set(ResourceDisplayName, 10), IPs = make_set(IPAddress, 10), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppName = coalesce(AppDisplayName, ServicePrincipalName), AppId | sort by Rows desc ``` When the resource doesn't exist, `ResourceIdentity` and `ResourceDisplayName` may be empty. Microsoft doesn't document this. If so, take the resource name from the error text the user or app received. Recent changes to apps, to find a resource that was disabled. Microsoft lists **Update service principal** and **Update application** as audit activities. Our assumption: switching off **Enabled for users to sign-in?** or deactivating an app registration is recorded under one of them. ```kusto AuditLogs | where TimeGenerated > ago(30d) | where Category == "ApplicationManagement" | where OperationName in ("Update service principal", "Update application") | extend Target = tostring(TargetResources[0].displayName), ByUser = tostring(InitiatedBy.user.userPrincipalName) | project TimeGenerated, OperationName, Target, ByUser, Result | sort by TimeGenerated desc ``` For app-only rows, check in your workspace that `ResultType` carries `"50001"` and not *"Failure"*. `ResultType` is a **string** column, so compare it with `"50001"`. ## How do I fix AADSTS50001? **For the user:** you can't fix this. Send IT the app name and the full error, including the resource name. **For developers:** 1. Compare the resource URL or scope in your code or settings with the API's identifier. Microsoft's description says to *"ensure that you have specified the exact resource URL for the resource you're trying to access."* 2. For your own API, check that its App ID URI is registered and that the client asks for exactly that value. **For admins:** 1. Find the resource under **Enterprise applications**. If it isn't there, treat it like [500011](https://brambrinkmeier.com/entra/aadsts/500011/): the resource was never set up in your tenant. 2. Open its **Properties** and check **Enabled for users to sign-in?**. Microsoft: when it is **No**, *"Tokens aren't issued for the application."* Microsoft documents a disabled resource service principal as [500014](https://brambrinkmeier.com/entra/aadsts/500014/), so if you find it switched off, read that page. 3. Check **App registrations** > **Deactivated applications**. Microsoft says a deactivated app *"immediately stops receiving new access tokens"*, but doesn't say what other apps get when they ask for a token to its API. To undo it, select the app and **Reactivate**. 4. Only re-enable a resource if disabling it was a mistake. Someone may have switched it off on purpose; the third query shows who changed it. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Properties of an enterprise application](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/application-properties) 3. [Deactivate an app registration](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/deactivate-app-registration) 4. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) 5. [Error AADSTS50001: the application named was not found in the tenant (Nintex community, user report)](https://community.nintex.com/nintex-for-office-365-68/error-aadsts50001-the-application-named-was-not-found-in-the-tenant-named-16156) 6. [AADSTS50001 error on Web API with Azure AD (Fabric community, user report)](https://community.fabric.microsoft.com/t5/Desktop/AADSTS50001-error-on-Web-API-with-Azure-AD/m-p/83032) ## Related codes [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS500014](https://brambrinkmeier.com/entra/aadsts/500014/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS7000112](https://brambrinkmeier.com/entra/aadsts/7000112/), [AADSTS65005](https://brambrinkmeier.com/entra/aadsts/65005/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50001 fix: resource disabled or doesn't exist", https://brambrinkmeier.com/entra/aadsts/50001/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50011/ # AADSTS50011: Reply URL does not match Canonical: https://brambrinkmeier.com/entra/aadsts/50011/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50011.json **Short answer:** AADSTS50011 means the redirect (reply) URI in the sign-in request doesn't exactly match one registered for the application. It is almost always a configuration mistake: http instead of https, a trailing slash, a wrong port. The exact-match rule is also what stops attackers redirecting authorization codes and tokens to their own server. **Fix:** Developer or admin: compare the redirect URI in the failing request character for character with the app registration (Authentication, or Basic SAML configuration > Reply URL) and add the exact URI. Don't add a wildcard. User: report the app name and time to IT or the app owner. | Field | Value | |---|---| | Code | AADSTS50011 | | Microsoft name | InvalidReplyTo | | Category | App configuration | | Type | Failure | | Attack signal | Low: usually configuration or user error | | MITRE ATT&CK | [T1528](https://attack.mitre.org/techniques/T1528/) Steal Application Access Token | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS50011 mean? Microsoft's description: > **InvalidReplyTo**: The reply address is missing, misconfigured, or doesn't match reply addresses configured for the app. As a resolution ensures to add this missing reply address to the Microsoft Entra application or have someone with the permissions to manage your application in Microsoft Entra IF do this for you. (The wording, including "IF", is Microsoft's.) The troubleshooting article shows the message users see: > The reply URL does not match the reply URLs configured for the application . Make sure the reply URL sent in the request matches one added to your application For SAML apps, the article names the cause as the `AssertionConsumerServiceURL` in the request not matching the Reply URL configured on the app. ## Is it an attack? Almost always not. The common causes are small differences between what the app sends and what is registered: - `http://` vs `https://` - a trailing slash, or a different path or port - a new environment (staging, a new hostname) that was never added to the app registration - a SAML app whose service provider sends a different ACS URL than the one configured The security point is the control behind the error. Entra ID only sends an authorization code or token to a redirect URI the app owner registered. **If that check were loose, an attacker could send a victim a sign-in link with their own server as the redirect and collect the code or token.** 50011 is that check refusing. | Pattern | Likely meaning | |---|---| | Errors right after a deployment or hostname change | Missing reply URL. Benign. | | One app, one wrong URI, many users | App misconfiguration. Benign, but users are blocked. | | One app, **many different** redirect URIs, from one IP or a few users | Someone testing which redirect values the app accepts. Investigate. | | 50011 for an app ID you don't recognise | Check whether the app is yours at all. See also 700016. | The probing pattern is **our reasoning** about how an attacker would look for a lax reply URL. Microsoft's troubleshooting article doesn't discuss security implications. ## How do I find it in my logs (KQL)? 50011 per app per day, to spot misconfigurations after changes: ```kusto SigninLogs | where TimeGenerated > ago(14d) | where ResultType == "50011" | summarize Users = dcount(UserPrincipalName), Attempts = count(), IPs = dcount(IPAddress) by AppDisplayName, AppId, bin(TimeGenerated, 1d) | sort by TimeGenerated desc, Attempts desc ``` Few sources, many attempts against one app: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50011" | summarize Attempts = count(), Apps = dcount(AppId), AppNames = make_set(AppDisplayName, 5), Users = make_set(UserPrincipalName, 5), UserAgents = make_set(UserAgent, 5) by IPAddress | sort by Attempts desc ``` The sign-in logs don't record the redirect URI that was sent, as far as the documented `SigninLogs` columns show. To see the exact value, use the error page or the request itself (browser developer tools, or the app's own logs). Volume and source are what you can hunt on in the logs. ## How does Conditional Access affect it? - 50011 is not a Conditional Access result. The request fails on application configuration before a token can be issued. - Conditional Access doesn't protect against a lax reply URL. If an app registration accepts a redirect URI you don't control, a user who completes sign-in, MFA and device checks still sends the code to that URI. Review the registered reply URLs as part of app hygiene. ## How do I fix AADSTS50011? **For the user:** this isn't something you can fix. Report the app name and the time to IT or the app owner. **For developers and admins:** 1. Read the redirect URI from the failing request and compare it character for character with the app registration (**Authentication** for OIDC/OAuth apps, **Basic SAML configuration** > Reply URL for SAML apps). 2. Add the exact URI the app uses. Don't add a broad or wildcard pattern to make the error go away. 3. Remove reply URLs for environments that no longer exist. A registered URI on a domain you let expire can be taken over and used to receive codes (reasoning, not a Microsoft statement). ## Practice the attack side The [Close enough lab](https://brambrinkmeier.com/labs/redirect-prefix/) is a local exercise where a redirect URI check that only compares the start of the string leaks an authorization code. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Troubleshoot error AADSTS50011 (reply URL mismatch)](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50011-reply-url-mismatch) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS50105](https://brambrinkmeier.com/entra/aadsts/50105/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS500031](https://brambrinkmeier.com/entra/aadsts/500031/), [AADSTS500113](https://brambrinkmeier.com/entra/aadsts/500113/), [AADSTS700051](https://brambrinkmeier.com/entra/aadsts/700051/), [AADSTS700054](https://brambrinkmeier.com/entra/aadsts/700054/), [AADSTS750054](https://brambrinkmeier.com/entra/aadsts/750054/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50011: Reply URL does not match", https://brambrinkmeier.com/entra/aadsts/50011/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50013/ # AADSTS50013 fix: invalid assertion in on-behalf-of flow Canonical: https://brambrinkmeier.com/entra/aadsts/50013/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50013.json **Short answer:** AADSTS50013 means Entra rejected an assertion, usually the user's access token that a middle-tier API tried to exchange in the on-behalf-of (OBO) flow. Microsoft lists issuer mismatch, expiry and malformed tokens as causes. One reported cause is an API that was handed a token meant for Microsoft Graph instead of for itself. Low attack value; fix the token the API receives. **Fix:** Developer: make the client request a token for your own API's scope (`api:///`), not for Microsoft Graph, and pass that token as the OBO assertion. Don't use an app with a custom signing key as the middle tier. User: report the error to the app's developer. | Field | Value | |---|---| | Code | AADSTS50013 | | Microsoft name | InvalidAssertion | | Category | Tokens and sessions | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS50013 mean? Microsoft's description: > **InvalidAssertion**: Assertion is invalid because of various reasons - The token issuer doesn't match the API version within its valid time range -expired -malformed - Refresh token in the assertion isn't a primary refresh token. Contact the app developer. An *assertion* is a token that an app hands to Entra ID as proof of something, and Entra ID refused it. The error comes back as `invalid_grant`, which Microsoft describes as *"some of the authentication material (auth code, refresh token, access token, PKCE challenge) was invalid, unparseable, missing, or otherwise unusable"*. Most user reports of 50013 come from the **on-behalf-of (OBO) flow**. A client calls your API with an access token. Your API sends that token to Entra ID in the `assertion` parameter and asks for a new token to call another API, often Microsoft Graph. Microsoft's OBO reference sets the rule for that token: *"This token must have an audience (`aud`) claim of the app making this OBO request (the app denoted by the `client-id` field). Applications can't redeem a token for a different app (for example, if a client sends an API a token meant for Microsoft Graph, the API can't redeem it using OBO. It should instead reject the token."* The message usually carries a reason in brackets. The ones users post: - *"Assertion failed signature validation. [Reason - Key was found, but use of the key to verify the signature failed.]"* - *"Assertion failed signature validation. [Reason - The key was not found.]"* Microsoft doesn't map these reasons to causes. See the table below for what users found. Don't confuse it with [700024](https://brambrinkmeier.com/entra/aadsts/700024/). That code is about the **client assertion**, the signed JWT an app uses to prove its own identity. 50013 is about the assertion being exchanged, in OBO the user's token. ## Is it an attack? Usually not. It is a developer error in how the app passes tokens around. Microsoft's own text ends with *"Contact the app developer."* | Pattern | Likely meaning | |---|---| | "Key was found, but use of the key to verify the signature failed", from a backend calling Graph via OBO | The client sent the API a **Microsoft Graph** token and the API tried to exchange it. In one Q&A thread the frontend requested Graph scopes and the backend passed that token on; the cause wasn't confirmed there. Microsoft says Graph tokens have a *"proprietary format"* and can't be validated like other tokens; our reading is that this is why the signature check fails. | | "The key was not found", and the token's `kid` only appears in metadata fetched with `?appid=` | The middle-tier app has a **custom signing key**. A user reports exactly this. Microsoft: *"applications with custom signing keys can't be used as middle-tier APIs in the OBO flow. This includes enterprise applications configured for single sign-on."* | | 50013 that mentions expiry | The client passed an expired access token. Get a fresh one before calling the API. | | 50013 for one app, starting right after a release | The new version changed which scope the client requests. | | 50013 from an unfamiliar IP for an app you own, with no successes | Someone is sending tokens your app didn't issue to the token endpoint. Our interpretation: a forged or tampered token would also fail signature validation and land here. Not documented by Microsoft, but worth a look. | A token with a bad signature gets nothing from Entra ID, so the failure itself grants no access. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table an OBO failure lands in. OBO is a sign-in *"performed by a client app or OS components on behalf of a user"*, which fits the non-interactive log, but we haven't checked. Look in all three: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "50013" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which app fails, for which downstream API, and with which reason. We assume `ResultDescription` carries the bracketed reason; Microsoft documents it only as *"the error message or the reason for failure"*: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "50013" | extend Reason = extract(@"Reason - ([^\]]+)", 1, ResultDescription) | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated) by AppDisplayName, AppId, ResourceDisplayName, Reason | sort by Rows desc ``` 50013 for apps that had no successful sign-in in the last 14 days. A starting point for spotting tokens sent to an app from somewhere it doesn't normally run; tune the window to your tenant: ```kusto let failing = union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "50013" | summarize Fails = count(), IPs = make_set(IPAddress, 10) by AppId, AppDisplayName; let working = union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(14d) | where ResultType == "0" | distinct AppId; failing | join kind=leftanti working on AppId | sort by Fails desc ``` `ResultType` is a **string** column, so compare it with `"50013"`, not `50013`. Non-interactive rows are aggregated when application, user, IP address, status and resource match, so row counts there are not request counts. ## How do I fix AADSTS50013? **For the user:** you can't fix this yourself. Report the error, with the time and the Correlation ID, to whoever runs the app. **For developers:** 1. Decode the token you pass as `assertion` (Microsoft names [jwt.ms](https://jwt.ms) for debugging only). Its `aud` must be **your API's** client ID or App ID URI. If it points at Microsoft Graph (`https://graph.microsoft.com`), the client asked for the wrong token. 2. Expose a scope on your API (App registrations > your API > **Expose an API**) and have the client request that scope, for example `api:///access_as_user`. The accepted Q&A answer gives these steps; the scope name is your choice. 3. If your API receives a token whose audience is Microsoft Graph rather than your API, reject it. Microsoft's OBO reference says exactly that: the API *"should instead reject the token"*. The fix is on the client side: have it request a token for your API's own scope. 4. Check the middle-tier app has no custom signing key (claims mapping, or an enterprise app configured for SAML SSO). Microsoft says those apps can't be OBO middle tiers. Use a separate app registration for the API. 5. Send a fresh, unexpired access token. Don't cache and replay an old one. 6. Set `requested_token_use` to `on_behalf_of`, as Microsoft requires. **For admins:** 1. Use the second query to find the app and the reason, and send both to the app's owner. 2. If an enterprise app with SAML SSO is also used as an API, that is the custom-signing-key case above. The fix is a separate app registration, not a setting. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and OAuth 2.0 On-Behalf-Of flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-on-behalf-of-flow) 3. [Access tokens in the Microsoft identity platform](https://learn.microsoft.com/entra/identity-platform/access-tokens) 4. [What are non-interactive user sign-ins in Microsoft Entra?](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 6. [AADSTS50013: Assertion failed signature validation (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/1412022/aadsts50013-assertion-failed-signature-validation) 7. [50013 Key Not Found issue in OBO flow (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/2057475/50013-key-not-found-issue-in-obo-flow-((error-inva) 8. [Getting AADSTS50013 while trying to create GraphServiceClient (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/1822322/getting-aadsts50013-while-trying-to-create-graphse) ## Related codes [AADSTS700024](https://brambrinkmeier.com/entra/aadsts/700024/), [AADSTS90023](https://brambrinkmeier.com/entra/aadsts/90023/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50013 fix: invalid assertion in on-behalf-of flow", https://brambrinkmeier.com/entra/aadsts/50013/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50020/ # AADSTS50020: Account from identity provider not in tenant Canonical: https://brambrinkmeier.com/entra/aadsts/50020/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50020.json **Short answer:** AADSTS50020 means an account from another identity provider or tenant tried to sign in to an app in your tenant, and that account isn't a user or guest there. It is usually a B2B or app misconfiguration: wrong tenant, uninvited guest, single-tenant app. Repeated hits can also reveal orphaned guest accounts that need cleanup. **Fix:** User: sign out, then sign in with the account your organisation gave you. Partner? Ask your contact to invite you as a guest. Admin: invite the user via B2B if they need access. For a guest that used to work, reset the guest's redemption status instead of deleting and re-inviting. | Field | Value | |---|---| | Code | AADSTS50020 | | Microsoft name | UserUnauthorized | | Category | Guests and tenants | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-25 | ## What does AADSTS50020 mean? Microsoft's description: > **UserUnauthorized**: Users are unauthorized to call this endpoint. User account '{email}' from identity provider '{idp}' does not exist in tenant '{tenant}' and cannot access the application '{appid}'({appName}) in that tenant. This account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Microsoft Entra user account. If this user should be a member of the tenant, they should be invited via the B2B system. ## Is it an attack? Usually not. Microsoft's troubleshooting article lists these causes: - A personal Microsoft account used to sign in to an admin portal. - A single-tenant app (`signInAudience`) being used by accounts from another tenant. - The app sends users to the wrong authority endpoint (`/common` versus a specific tenant). - The user is signed in to the wrong tenant in the browser. - The external user was never invited as a guest. - The app requires assignment. - ROPC (username/password flow) used with personal accounts. - The user was deleted and re-created in their home tenant, which leaves the old guest object in your tenant **orphaned**. | Pattern | Likely meaning | |---|---| | A partner user, first time on an app | Not invited yet, or wrong tenant in the link. Benign. | | A known guest who used to work, now fails | **Orphaned guest.** Their home account was re-created. Lifecycle cleanup, not an attack. | | Your own staff on a partner's app | Wrong authority or single-tenant app on the partner side. Benign. | | Many different external identities you never invited, against one or several of your apps | Someone checking which of your apps accept outside accounts. Investigate. | The last row is **our reasoning**, not a Microsoft statement. Microsoft documents 50020 as a configuration error. The orphaned-guest case is the more useful finding for most tenants: it shows guest objects whose real-world identity no longer matches. ## How do I find it in my logs (KQL)? Which external identities hit 50020, against which apps: ```kusto SigninLogs | where TimeGenerated > ago(14d) | where ResultType == "50020" | summarize Attempts = count(), Apps = make_set(AppDisplayName, 10), IPs = make_set(IPAddress, 10), HomeTenants = make_set(HomeTenantId, 5), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by UserPrincipalName | sort by Attempts desc ``` Possible probing: one IP, many distinct external identities: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50020" | summarize Identities = dcount(UserPrincipalName), Apps = make_set(AppDisplayName, 10), Attempts = count() by IPAddress | where Identities >= 5 | sort by Identities desc ``` The `UserPrincipalName` on a 50020 row is the identity that tried to sign in, which by definition isn't a user in your tenant. Check one row in your workspace to see how it is filled before you rely on it; the email in the error message may be hidden or differ. The threshold of 5 is a starting point, not a tested value. To find orphaned guests, compare the identities above with your guest list. A guest whose email matches a 50020 identity existed in your tenant but no longer matches its home account. ## How does Conditional Access affect it? - 50020 is not a Conditional Access result. The account isn't in your tenant, so there is no user for your policies to evaluate. - Once the external user is invited and redeems the invitation, your policies for guests and external users apply to them like any other sign-in. Have those guest policies in place before you invite. - Cross-tenant access settings decide which outside organisations can collaborate at all. They are the place to limit B2B access, not exclusions in individual apps. ## How do I fix AADSTS50020? **For the user:** sign out, then sign in again with the account your organisation gave you. If you are a partner, ask your contact to invite you as a guest. **For admins and developers:** 1. Check the tenant and app in the error. If the user should have access, invite them via B2B. 2. For an orphaned guest (home account re-created), reset the guest's redemption status. Microsoft's article: *"Reset the redemption status of the guest user account in the resource tenant. Then, you can keep the guest user object without having to delete and then re-create the guest account."* 3. For your own app: check `signInAudience` and the authority URL. A multi-tenant app shouldn't send users to a single tenant's endpoint, and a single-tenant app shouldn't be offered to outside users. 4. Review guest accounts on a schedule. Orphaned guests are inactive objects with access rights that nobody uses. ## Practice the attack side The [Whose email is it? lab](https://brambrinkmeier.com/labs/tenant-trust/) is a local exercise where a multi-tenant app trusts a token from any tenant and looks users up by email. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Troubleshoot error AADSTS50020 (user account from identity provider does not exist in tenant)](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50020-user-account-identity-provider-does-not-exist) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS90072](https://brambrinkmeier.com/entra/aadsts/90072/), [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS50105](https://brambrinkmeier.com/entra/aadsts/50105/), [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), [AADSTS16000](https://brambrinkmeier.com/entra/aadsts/16000/), [AADSTS50059](https://brambrinkmeier.com/entra/aadsts/50059/), [AADSTS50194](https://brambrinkmeier.com/entra/aadsts/50194/), [AADSTS51004](https://brambrinkmeier.com/entra/aadsts/51004/), [AADSTS500021](https://brambrinkmeier.com/entra/aadsts/500021/), [AADSTS500200](https://brambrinkmeier.com/entra/aadsts/500200/), [AADSTS500571](https://brambrinkmeier.com/entra/aadsts/500571/), [AADSTS5000211](https://brambrinkmeier.com/entra/aadsts/5000211/), [AADSTS9002331](https://brambrinkmeier.com/entra/aadsts/9002331/), [AADSTS9002346](https://brambrinkmeier.com/entra/aadsts/9002346/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50020: Account from identity provider not in tenant", https://brambrinkmeier.com/entra/aadsts/50020/ (CC BY 4.0), last updated 2026-10-25. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50027/ # AADSTS50027: JWT token is invalid or malformed (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/50027/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50027.json **Short answer:** AADSTS50027 means Microsoft Entra ID received a JWT it would not accept: wrong format, missing or duplicated claims, unexpected issuer or audience, outside its valid time range, or a failed signature check on an external ID token. It is usually a developer error. The two common sources are a hand-built client assertion and a federated identity provider's ID token. **Fix:** Developer sending a client assertion: build a real JWT with the header and claims Microsoft documents, signed with the certificate registered on the app. Federation admin: fix the issuer, audience or signing key on the identity provider. | Field | Value | |---|---| | Code | AADSTS50027 | | Microsoft name | InvalidJwtToken | | Category | Credentials and lockout | | Type | Failure | | Attack signal | Medium: worth a look in context | | Where to look | `SigninLogs`, `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS50027 mean? Microsoft's description: > **InvalidJwtToken**: Invalid JWT token because of the following reasons: > - doesn't contain nonce claim, sub claim > - subject identifier mismatch > - duplicate claim in idToken claims > - unexpected issuer > - unexpected audience > - not within its valid time range > - token format isn't proper > - External ID token from issuer failed signature verification. That is eight different conditions behind one code, which is why the fix depends entirely on which JWT Entra was looking at. Two kinds of request put a JWT in front of Entra: - **A client assertion.** An app authenticating with a certificate or a federated credential sends `client_assertion` instead of a secret. Our lab hit 50027 this way. - **An external ID token.** A federated identity provider returns an ID token to Entra, which validates it. The last bullet in Microsoft's list, *"External ID token from issuer failed signature verification"*, is this case, and so are the `nonce`, `sub` and duplicate-claim bullets, which name `idToken` explicitly. For the client assertion case, Microsoft's certificate credentials page documents what the JWT must contain. The header: | Parameter | Microsoft's remark | |---|---| | `alg` | Should be **PS256** | | `typ` | Should be **JWT** | | `x5t#S256` | Base64url-encoded SHA-256 thumbprint of the X.509 certificate's DER encoding. | And the claims: `aud` (`https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token`), `iss` and `sub` (both the client ID), `jti`, `nbf`, `exp` and `iat`. On the lifetime, Microsoft says to *"keep it short - 5-10 minutes after `nbf` at most"*. The signature *"is computed by applying the certificate as described in the JSON Web Token RFC7519 specification"*, using PSS padding. Several of Microsoft's eight bullets map onto that table: `aud` wrong is "unexpected audience", `iss` wrong is "unexpected issuer", and an `exp` in the past is "not within its valid time range". ### Which assertion error you get, and in what order Our lab separated three of the assertion failures. Entra checks them in this order: | What is wrong | Code | |---|---| | `client_assertion_type` is not the JWT bearer URN | [90023](https://brambrinkmeier.com/entra/aadsts/90023/) *"Unexpected client assertion type."* | | The assertion is not a well-formed JWT | **50027** | | The assertion is a JWT but its validity window has passed or not begun | [700024](https://brambrinkmeier.com/entra/aadsts/700024/) | | Nothing was sent at all on a `client_credentials` request | [7000216](https://brambrinkmeier.com/entra/aadsts/7000216/) | Microsoft's reference also lists **AADSTS700027**, *"Client assertion failed signature validation"*, for a well-formed JWT with a bad signature. So 50027 sits between "wrong kind of parameter" and "right shape, wrong signature": the string reached the JWT parser and the parser rejected it. ## Reproduced in the lab On 30 October 2026 an automated lab run sent a client-credentials token request with the correct `client_assertion_type` and a `client_assertion` that was not a JWT. Entra returned: > AADSTS50027: JWT token is invalid or malformed. Both rounds of the run returned the same code and the same one-line message, short enough that the lab's 160-character cut does not truncate it. The run had expected 9002313, 50027 or 700027, and 50027 is the one it got. In the same run, the same request with an unaccepted `client_assertion_type` returned [90023](https://brambrinkmeier.com/entra/aadsts/90023/), and a syntactically valid assertion whose validity window had passed returned [700024](https://brambrinkmeier.com/entra/aadsts/700024/) with the current time and the assertion's `nbf` in the message. So the lab confirms the format case specifically, and not the other seven conditions in Microsoft's list. No sign-in log row was captured. See [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? Usually not, and this is the one code on this page's family where the answer deserves a second look. A malformed JWT is what a developer produces; it is also what someone replaying or editing a captured token produces. | Pattern | Likely meaning | |---|---| | Repeated 50027 for one app from your own build agents or servers | A client assertion implementation under development, or a certificate rotation that went wrong. Benign. | | 50027 on an app that has worked for months, with no deployment | Look at the certificate. An expired or replaced certificate usually gives a different code, but a half-finished rotation can produce assertions nobody can parse. | | 50027 for one app from an address you don't own | Someone is sending assertions for your app ID. They do not have a working credential, or you would see a success instead. Check for successes from the same address. | | 50027 on user sign-ins through a federated identity provider | The identity provider's ID token is being rejected. Check the issuer, the audience and the signing key on the provider, and whether a certificate was rolled. | | A burst across several apps from one address | Someone is probing with crafted tokens. Nothing is disclosed by this error, but the source is worth a look. | Our reading on the signal: 50027 means a token was refused, so it is evidence of a failure rather than of a compromise. What makes it worth watching is a success from the same source shortly after. ## How do I find it in my logs (KQL)? Which table 50027 lands in depends on which JWT failed, and Microsoft doesn't document it for either case. Our reading: a client assertion is an app signing in, so `AADServicePrincipalSignInLogs`; a federated user's ID token is a user sign-in, so `SigninLogs` or `AADNonInteractiveUserSignInLogs`. Start with the union: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "50027" or ResultSignature == "50027" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Apps = make_set(AppId, 10) by SourceTable ``` The filter covers both columns because the tables describe them differently: in `SigninLogs`, `ResultType` *"provides the 5-6 digit error code that's generated during a sign-in event"*, while `AADServicePrincipalSignInLogs` describes `ResultType` as *"Success or Failure"* and `ResultSignature` as *"the error code, if any, for the sign-in operation"*. For the client assertion case, which app and which source: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "50027" or ResultSignature == "50027" | summarize Failures = count(), LastSeen = max(TimeGenerated), CredentialTypes = make_set(ClientCredentialType, 5), Thumbprints = make_set(ServicePrincipalCredentialThumbprint, 5), Descriptions = make_set(ResultDescription, 5) by AppId, ServicePrincipalName, IPAddress | sort by Failures desc ``` `ClientCredentialType` is documented as *"the type of client credential used. Examples include client assertion, client secret, etc."* Whether it and the thumbprint column are filled in when the JWT could not be parsed is not documented: a token Entra cannot read may not identify a credential at all. Check a row before you rely on either column. The pattern worth alerting on is a refusal followed by a success from the same place: ```kusto let failedFrom = AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "50027" or ResultSignature == "50027" | summarize FirstFail = min(TimeGenerated) by AppId, IPAddress; AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "0" or ResultType =~ "Success" | join kind=inner failedFrom on AppId, IPAddress | where TimeGenerated > FirstFail | project TimeGenerated, AppId, ServicePrincipalName, IPAddress, ClientCredentialType, FirstFail | sort by TimeGenerated asc ``` Thresholds are a starting point only: for a developer's own address, dozens an hour mean nothing; for an address with no history for that app, one row is enough to look at. ## How does Conditional Access affect it? Not relevant to the client assertion case: there is no user and no policy evaluation, and the request fails on the credential. For the federated user case, 50027 happens while Entra is validating the incoming token, which is before the point where Conditional Access decides anything. Our reading, by analogy with other first-factor failures; Microsoft doesn't state it for this code. ## How do I fix AADSTS50027? **For developers sending a client assertion:** 1. Decode what you are sending. If it isn't three base64url segments separated by dots, it is not a JWT and nothing else matters. 2. Build the header with `alg` PS256, `typ` JWT and `x5t#S256` set to the certificate's SHA-256 thumbprint, and the claims `aud`, `iss`, `sub`, `jti`, `nbf`, `exp` and `iat` as Microsoft's certificate credentials page specifies. `iss` and `sub` are both the client ID. 3. Keep the lifetime short, 5 to 10 minutes after `nbf`. If the window has passed you get [700024](https://brambrinkmeier.com/entra/aadsts/700024/) rather than 50027. 4. Sign with the private key of a certificate registered on the app registration, using PSS padding. 5. Let a library do it. MSAL builds the assertion from a certificate for you, and most 50027 in this case comes from hand-rolled code. 6. Send it with `client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer`, or you get [90023](https://brambrinkmeier.com/entra/aadsts/90023/) first. **For admins of a federated identity provider:** 1. Work out which of Microsoft's eight conditions applies before changing anything. The `nonce`, `sub`, duplicate-claim and signature-verification bullets are all about an external ID token. 2. Check the issuer and audience values configured on both sides, and that the provider's current signing key is the one Entra is reading. A key rollover on the provider gives *"External ID token from issuer failed signature verification"*. 3. Check clock skew. *"Not within its valid time range"* is a time problem on the provider, not in Entra. **For admins generally:** 1. Use the queries above to identify the app and its owner, and whether any source that failed also succeeded. 2. If an address with no history for the app is sending assertions, treat the app ID as known to someone outside and review the app's permissions. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Client-credentials token request against a lab tenant; scenario: Client assertion that is not a JWT). First line returned: > AADSTS50027: JWT token is invalid or malformed. Lab-run rows naming this code (7; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-30 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-30 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-30 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-30 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-31 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-31 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform application authentication certificate credentials](https://learn.microsoft.com/en-us/entra/identity-platform/certificate-credentials) 3. [Microsoft identity platform and the OAuth 2.0 client credentials flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow) 4. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS90023](https://brambrinkmeier.com/entra/aadsts/90023/), [AADSTS700024](https://brambrinkmeier.com/entra/aadsts/700024/), [AADSTS7000216](https://brambrinkmeier.com/entra/aadsts/7000216/), [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50027: JWT token is invalid or malformed (fix)", https://brambrinkmeier.com/entra/aadsts/50027/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50034/ # AADSTS50034 fix: user account not found in the tenant Canonical: https://brambrinkmeier.com/entra/aadsts/50034/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50034.json **Short answer:** AADSTS50034 means the username doesn't exist in the Microsoft Entra tenant the sign-in went to. Usually it's a typo or the wrong tenant. The security signal is volume from one source: many different non-existent usernames from one IP suggests an attacker testing a guessed or leaked user list. Hunt it with ResultType == "50034". **Fix:** User: check the spelling of your username and that you are using your work account. From another organisation? Ask the app owner to invite you as a guest. Admin: check for a typo, a renamed UPN or an app pointing at the wrong tenant, and add external users who need access as guests (B2B). | Field | Value | |---|---| | Code | AADSTS50034 | | Microsoft name | UserAccountNotFound | | Category | Credentials and lockout | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1087.004](https://attack.mitre.org/techniques/T1087/004/) Account Discovery: Cloud Account, [T1110.003](https://attack.mitre.org/techniques/T1110/003/) Brute Force: Password Spraying | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-25) | | Last updated | 2026-11-01 | ## What does AADSTS50034 mean? Microsoft's description: > **UserAccountNotFound**: To sign into this application, the account must be added to the directory. This error can occur because the user mis-typed their username, or isn't in the tenant. An application might have chosen the wrong tenant to sign into, and the currently logged in user was prevented from doing so since they did not exist in your tenant. If this user should be able to log in, add them as a guest. No account with that name exists in the tenant that received the request. No password check happened against a real account. ## Reproduced in the lab On 25 October 2026 an automated lab run sent a token request for a user name that doesn't exist in my lab tenant. Entra returned `AADSTS50034` with this first line: > AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. That confirms the code and its wording at the token endpoint. The sign-in log row and the KQL on this page are not checked against it yet; see [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? Microsoft's description lists three benign causes: a typo, a user who isn't in the tenant, and an app that picked the wrong tenant. Those explain most rows. The pattern decides: | Pattern | Likely meaning | |---|---| | One attempt, then a success with the corrected name from the same IP | A typo. Benign. | | A user from a partner organisation, hitting one specific app | Wrong tenant or a missing guest invitation. Benign. Add them as a guest if they need access. | | A former employee's name, or a renamed user's old name | Something still uses the old username. Find and update it. | | Many **different** non-existent names from one IP | Likely an attacker testing a user list (interpretation, not checked against real data): guessed `firstname.lastname` formats or a leaked list (T1087.004). | | 50034 mixed with 50126 and 50057 from the same IP | A password spray using a list that contains real, disabled and non-existent names (T1110.003). | Conditional Access does not apply here. There is no user for a policy to match, and CA only runs after the first factor succeeds. Expect `ConditionalAccessStatus` = `notApplied`. ## How do I find it in my logs (KQL)? One IP trying many non-existent usernames: ```kusto SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50034" | summarize UnknownNames = dcount(UserPrincipalName), Attempts = count(), Sample = make_set(UserPrincipalName, 20), Apps = make_set(AppDisplayName, 5), Clients = make_set(ClientAppUsed, 5) by IPAddress | where UnknownNames >= 10 | sort by UnknownNames desc ``` The same IPs, across all credential failures: how many real accounts were also hit, and did anything get through? ```kusto let enumIPs = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50034" | summarize UnknownNames = dcount(UserPrincipalName) by IPAddress | where UnknownNames >= 10 | project IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where IPAddress in (enumIPs) | summarize Attempts = count(), Users = dcount(UserPrincipalName) by IPAddress, ResultType, ResultDescription | sort by IPAddress asc, Attempts desc ``` Any `ResultType` of `"0"`, `"50076"`, `"50074"` or `"53003"` in the second result means a password was correct for at least one account. Pivot on that IP and user. For a non-existent account, check which column holds the name that was typed. It is probably `UserPrincipalName` (an assumption, not yet checked against real data). `SignInIdentifier` is documented as *"populated when a user signs in using other identifiers"*, so look there as well. ## How do Conditional Access and MFA affect it? - Conditional Access and MFA play no part in a 50034. The request fails before either is evaluated. - The sign-in itself gives the attacker little, but the different answers do. A non-existent name returns 50034 and a real name with a wrong password returns 50126, so in practice the error alone can tell an attacker which names are real. The risk is the **next step**: the confirmed names get sprayed. Watch the same IPs for 50126 and 50053. ## How do I fix AADSTS50034? **For the user:** check the spelling of your username and that you are signing in with your work account. If you are from another organisation, ask the app owner to invite you as a guest. **For admins:** 1. Single user: check for a typo, a renamed UPN, or an app pointing at the wrong tenant. 2. External user who needs access: add them as a guest (B2B), as Microsoft's description says. 3. Enumeration pattern: you can't block it at the Entra ID layer, because Conditional Access never evaluates a request for a user that doesn't exist. Put the IP on a watchlist or threat-intel feed instead, and watch for follow-up 50126/50053 from the same range. If the names come in a predictable format, that is a hint your UPN convention is public. 4. Make sure every **real** account has MFA, so a list of valid names plus a sprayed password isn't enough. ## Evidence Reproduced in a lab tenant on 2026-10-25 (ROPC token request against a lab tenant; scenario: User does not exist). First line returned: > AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. Lab-run rows naming this code (24; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | User does not exist | 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | User does not exist | 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | User does not exist | 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-30 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | User does not exist | 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-30 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | User does not exist | 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-30 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | User does not exist | 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-30 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | User does not exist | 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-31 | User does not exist | 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-31 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-31 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-31 | User does not exist | 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-31 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-31 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Sign-in log activity details](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-in-log-activity-details) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50053](https://brambrinkmeier.com/entra/aadsts/50053/), [AADSTS50057](https://brambrinkmeier.com/entra/aadsts/50057/), [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS16000](https://brambrinkmeier.com/entra/aadsts/16000/), [AADSTS50052](https://brambrinkmeier.com/entra/aadsts/50052/), [AADSTS51004](https://brambrinkmeier.com/entra/aadsts/51004/), [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS90019](https://brambrinkmeier.com/entra/aadsts/90019/), [AADSTS500200](https://brambrinkmeier.com/entra/aadsts/500200/), [AADSTS500341](https://brambrinkmeier.com/entra/aadsts/500341/), [AADSTS500571](https://brambrinkmeier.com/entra/aadsts/500571/), [AADSTS5000225](https://brambrinkmeier.com/entra/aadsts/5000225/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50034 fix: user account not found in the tenant", https://brambrinkmeier.com/entra/aadsts/50034/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50052/ # AADSTS50052: Password exceeds the maximum length (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/50052/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50052.json **Short answer:** AADSTS50052 means the password sent was longer than Entra's limit of 256 characters. Microsoft's error reference doesn't list it, but a Microsoft change notice from 2020 names it InvalidPasswordExceedsMaxLength. Usually a user with an old over-long password, or a tool that sends garbage. Low attack value. Reset the password to 256 characters or fewer. **Fix:** User: ask your admin to reset your password, or use 'Forgot your password' if your organisation allows self-service reset, and pick one of 256 characters or fewer. Admin: reset it to 8 to 256 characters. Developer: check what your code sends in the `password` field. | Field | Value | |---|---| | Code | AADSTS50052 | | Microsoft name | InvalidPasswordExceedsMaxLength | | Category | Credentials and lockout | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS50052 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS50052 (checked 30 October 2026). The lab reproduced it. A password-grant token request with a 300-character password returned: > AADSTS50052: The password entered exceeds the maximum length. Please reach out to your admin to reset the password. Microsoft documents the code on another page. Its "What's new for authentication?" page has a March 2020 entry, **"User passwords will be restricted to 256 characters"**, effective 13 March 2020, for all endpoints and all user flows: > Users with passwords longer than 256 characters who sign in directly to Microsoft Entra ID (not a federated IDP, like AD FS) will be asked to change their passwords before they can sign in. Admins may receive requests to help reset the user's password. > > The error in the sign-in logs will be similar to *AADSTS 50052: InvalidPasswordExceedsMaxLength*. That page gives the message as *"The password entered exceeds the maximum length of 256. Please reach out to your admin to reset the password."* The lab got the same text without "of 256". The limit itself is in Microsoft's password policy: *"A minimum of 8 characters and a maximum of 256 characters."* ## Reproduced in the lab On 30 October 2026 an automated lab run sent a password-grant (ROPC) token request for a test user in my lab tenant, with a 300-character password. Entra returned `AADSTS50052` with the first line quoted above. That confirms the code and the current wording at the token endpoint. Our reading: Entra checks the length before it checks the password. The current policy caps passwords at 256 characters, so a 300-character password can't match one set under it. It could only be wrong, yet the answer was the length error and not [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/). We did not test whether a user that doesn't exist gets 50052 too. It lands in **`SigninLogs`**: Status Failure, Conditional Access Not Applied. Entra's explanation on the row reads: *"The user is unable to login because their password exceeds the permitted maximum length. They should contact their admin to reset the password. If SSPR is enabled for their tenant, they can reset their password by following the "Forgot your password" link."* The KQL below was run on these rows ([how](https://brambrinkmeier.com/methodology/)). The first two queries found the row. The third returned nothing as written, as expected for one attempt; with its threshold lowered to 1 it found it. ## Is it an attack? Usually not. A real person rarely types 257 characters. | Pattern | Likely meaning | |---|---| | One user, repeated, from their usual devices | A password set before the March 2020 limit, or a sign-in tool or password manager that sends too much. The user needs a reset. | | One app or service account, every attempt | A script or config sending the wrong value as the password, such as a token, a certificate or a whole file. | | Many users from one IP, mixed with 50126 | A spray or stuffing tool sending broken or over-long entries from a bad list. Look at the 50126 rows; those are the real attempts. | The meanings in this table are our reading. Microsoft doesn't describe these patterns. A 50052 is a failed sign-in. No token is issued. ## How do I find it in my logs (KQL)? Microsoft's 2020 notice says the error shows in the sign-in logs, but doesn't say which table. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "50052" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Who hits it, from where, with which app: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "50052" | summarize Attempts = count(), LastSeen = max(TimeGenerated), IPs = make_set(IPAddress, 10), Apps = make_set(AppDisplayName, 5), Clients = make_set(ClientAppUsed, 5) by UserPrincipalName | sort by Attempts desc ``` IPs that produce 50052 for several users, with their other credential failures next to it. The threshold of 3 users is a starting point: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType in ("50052", "50126", "50034") | summarize Users = dcount(UserPrincipalName), TooLong = countif(ResultType == "50052"), WrongPassword = countif(ResultType == "50126"), UnknownUser = countif(ResultType == "50034") by IPAddress | where TooLong > 0 and Users >= 3 | sort by Users desc ``` ## How do I fix AADSTS50052? **For the user:** your password is longer than the 256 characters Entra allows. Ask your admin to reset it, or use "Forgot your password" if your organisation allows self-service reset. Microsoft's notice says: *"If SSPR is enabled for their tenant, they can reset their password by following the "Forgot your password" link."* Pick a new password of 256 characters or fewer. **For developers:** check what your code sends in the `password` field. If it is longer than 256 characters, it is almost certainly not the password. Probably a secret, token or file read into the wrong variable, though we haven't confirmed that. **For admins:** 1. Find the user with the queries above. 2. Reset the password to one of 256 characters or fewer. Microsoft's policy allows 8 to 256 characters. 3. If it is a service account used by a script, fix what the script sends, then look at why it uses a password grant at all. ## Evidence Reproduced in a lab tenant on 2026-10-30 (ROPC and other token-endpoint requests against a lab tenant; scenario: Password longer than 256 characters). First line returned: > AADSTS50052: The password entered exceeds the maximum length. Please reach out to your admin to reset the password. Sign-in log row read: 2026-10-30. KQL run against the exported lab rows: 2026-10-30. Lab-run rows naming this code (8; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Password longer than 256 characters | 50052 | 50052 | AADSTS50052: The password entered exceeds the maximum length. Please reach out to your admin to reset the password. | | 2026-10-30 | Password longer than 256 characters | 50052 | 50052 | AADSTS50052: The password entered exceeds the maximum length. Please reach out to your admin to reset the password. | | 2026-10-30 | Password longer than 256 characters | 50052 | 50052 | AADSTS50052: The password entered exceeds the maximum length. Please reach out to your admin to reset the password. | | 2026-10-30 | Password longer than 256 characters | 50052 | 50052 | AADSTS50052: The password entered exceeds the maximum length. Please reach out to your admin to reset the password. | | 2026-10-30 | Password longer than 256 characters | 50052 | 50052 | AADSTS50052: The password entered exceeds the maximum length. Please reach out to your admin to reset the password. | | 2026-10-30 | Password longer than 256 characters | 50052 | 50052 | AADSTS50052: The password entered exceeds the maximum length. Please reach out to your admin to reset the password. | | 2026-10-31 | Password longer than 256 characters | 50052 | 50052 | AADSTS50052: The password entered exceeds the maximum length. Please reach out to your admin to reset the password. | | 2026-10-31 | Password longer than 256 characters | 50052 | 50052 | AADSTS50052: The password entered exceeds the maximum length. Please reach out to your admin to reset the password. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [What's new for authentication? (Microsoft identity platform)](https://learn.microsoft.com/en-ca/entra/identity-platform/reference-breaking-changes) 3. [Password policies and account restrictions in Microsoft Entra ID](https://learn.microsoft.com/entra/identity/authentication/concept-sspr-policy) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50055](https://brambrinkmeier.com/entra/aadsts/50055/), [AADSTS50053](https://brambrinkmeier.com/entra/aadsts/50053/), [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50052: Password exceeds the maximum length (fix)", https://brambrinkmeier.com/entra/aadsts/50052/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50053/ # AADSTS50053: Account locked or sign-in blocked Canonical: https://brambrinkmeier.com/entra/aadsts/50053/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50053.json **Short answer:** AADSTS50053 covers two different blocks. Smart lockout locked the account after too many wrong passwords, or Microsoft's built-in protections blocked a high-confidence risky sign-in regardless of the password. The failure reason tells them apart. A burst across many accounts usually means a password spray tripped lockout. **Fix:** User: wait for the lockout to pass or reset your password with self-service reset, and stop retrying the old one. Admin: check the failure reason first. Lockout: find the phone or script sending the old password. Built-in block: move the client to modern authentication. | Field | Value | |---|---| | Code | AADSTS50053 | | Microsoft name | IdsLocked | | Category | Credentials and lockout | | Type | Failure | | Attack signal | High: often seen in attacks | | MITRE ATT&CK | [T1110.003](https://attack.mitre.org/techniques/T1110/003/) Brute Force: Password Spraying, [T1110.001](https://attack.mitre.org/techniques/T1110/001/) Brute Force: Password Guessing | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS50053 mean? Microsoft's description: > This error can result from two different reasons: **IdsLocked** - The account is locked because the user tried to sign in too many times with an incorrect user ID or password. The user is blocked due to repeated sign-in attempts. See Remediate risks and unblock users. Or, sign-in was blocked because it came from an IP address with malicious activity. To determine which failure reason caused this error, sign in to the Microsoft Entra admin center … Navigate to … Monitoring & health > Sign-in logs. Find the failed user sign-in with Sign-in error code 50053 and check the Failure reason. One code, two mechanisms. Read the failure reason before you decide what happened. For the full spray investigation, see [How to detect password spraying in Entra ID](https://brambrinkmeier.com/guides/detect-password-spray-entra-id/). **1. Smart lockout.** Too many wrong passwords. Microsoft's smart lockout page: > By default, smart lockout locks an account from sign-in after: 10 failed attempts in Azure Public and Microsoft Azure operated by 21Vianet tenants; Three failed attempts for Azure US Government tenants. The account locks again after each subsequent failed sign-in attempt. The lockout period is one minute at first, and longer in subsequent attempts. Microsoft also says smart lockout *"uses familiar location versus unfamiliar location to differentiate between a bad actor and the genuine user. Both unfamiliar and familiar locations have separate lockout counters."* **2. Built-in protection block.** The same smart lockout page says Entra ID *"blocks these malicious sign-ins by default and returns AADSTS50053 - IdsLocked error code, regardless of the password validity."* The ID Protection documentation adds: > Microsoft Entra ID Protection automatically blocks sign-ins that have a very high confidence of being risky. This block most commonly occurs on sign-ins performed using legacy authentication protocols or displaying properties of a malicious attempt. When a user is blocked for either scenario, they receive a 50053 authentication error. The sign-in logs display the following block reason: 'Sign-in was blocked by built-in protections due to high confidence of risk.' The important phrase is **"regardless of the password validity"**. A 50053 of this kind does not tell you whether the password was right or wrong. ## Reproduced in the lab On 30 October 2026 an automated lab run sent wrong passwords for one test user, two seconds apart, until Entra stopped accepting them. The eleventh attempt returned `AADSTS50053`: > AADSTS50053: The account is locked, you've tried to sign in too many times with an incorrect user ID or password. The run sent up to fifteen attempts and stopped at the first 50053, so the exact lockout threshold isn't recorded here; the earlier attempts returned [50126](https://brambrinkmeier.com/entra/aadsts/50126/). That ordering is the useful part: a spray that stops below the threshold leaves only 50126 rows behind, and 50053 appears only once an account crosses it. The sign-in log row isn't captured yet; see [how pages are checked](https://brambrinkmeier.com/methodology/). In the lab tenant's sign-in logs the 50053 appears under **User sign-ins (interactive)**, Status **Failure**, Conditional Access **Not Applied**, authentication requirement single-factor. The run order is visible in the log and is the useful part: in two separate runs, eleven and thirteen [50126](https://brambrinkmeier.com/entra/aadsts/50126/) rows for the same user and IP appear immediately before the 50053. So the lockout row is the end of a visible run of wrong-password rows, not an isolated event. Microsoft documents the smart lockout threshold as ten failed attempts by default; the counts seen here are the rows the portal showed, which is close to that but not an exact measurement of the threshold. ## Is it an attack? | Pattern | Likely meaning | |---|---| | One user, preceded by a handful of 50126 from their usual IP and device | The user forgot or mistyped the password and tripped smart lockout. Benign. | | Failure reason "Sign-in was blocked by built-in protections due to high confidence of risk" | Microsoft judged the sign-in malicious. Look at the IP and `ClientAppUsed`. Legacy protocols are the common case. | | Many **different users** hitting 50053 from one IP or range, after a run of 50126 | A **password spray** (T1110.003) that tripped lockout. | | Many 50053 against **one user** from unfamiliar IPs | Brute force against that account (T1110.001). | | 50053 on legacy clients (SMTP, IMAP, POP) for a service account or old device | Often a device or script with a stale password, or a legacy-auth spray. Check the IP. | | A success, 50076/50074 or 53003 from the same IP for a targeted user | The attacker found a correct password at some point. Treat that account as compromised. | Conditional Access does not run on a 50053. Microsoft's Conditional Access overview states: *"Conditional Access policies are enforced after first-factor authentication is completed."* So expect `ConditionalAccessStatus` = `notApplied` on these rows. ## How do I find it in my logs (KQL)? Split 50053 by mechanism. The built-in protection block is identified by its documented failure reason. Everything else under 50053 is most likely smart lockout (interpretation), but Microsoft does not publish the exact lockout wording, so check the `ResultDescription` values the query returns in your own workspace. ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50053" | extend FailureReason = tostring(Status.failureReason) | extend Mechanism = iff(ResultDescription has "built-in protections" or FailureReason has "built-in protections", "Built-in protection block", "Smart lockout (likely)") | summarize Events = count(), Users = dcount(UserPrincipalName), IPs = dcount(IPAddress), Clients = make_set(ClientAppUsed, 5) by Mechanism, ResultDescription | sort by Events desc ``` Spray that tripped lockout: one IP, many locked users, and did that IP ever get further than the password? ```kusto let lockoutIPs = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50053" | summarize LockedUsers = dcount(UserPrincipalName) by IPAddress | where LockedUsers >= 5 | project IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where IPAddress in (lockoutIPs) | where ResultType in ("0", "50076", "50074", "50079", "53003", "50055") | project TimeGenerated, UserPrincipalName, IPAddress, ResultType, ResultDescription, ConditionalAccessStatus, AppDisplayName, ClientAppUsed | sort by TimeGenerated asc ``` `ResultType` is a string, so compare with `"50053"`. Legacy clients such as SMTP AUTH can produce 50053 too. If you allow legacy auth, run the first query against `AADNonInteractiveUserSignInLogs` as well. There `Status` is a string, so use `tostring(parse_json(Status).failureReason)`. ## How do Conditional Access and MFA affect it? - CA can't prevent a 50053. Both mechanisms act at the credential stage, before CA evaluates. - Smart lockout is always on for every tenant. Changing the threshold or duration needs Entra ID P1. - **Blocking legacy authentication** with CA removes the protocols where the built-in block most commonly fires, and those protocols can't do MFA. - MFA does not stop the lockout itself. It decides what happens if the attacker ever gets the password right. ## How do I fix AADSTS50053? **For the user:** - Smart lockout: wait for the lockout period to pass, or reset the password with self-service password reset. Don't keep retrying the old password. Each further failure locks the account again, and later lockouts last longer. - Built-in block: sign in from a familiar location and a modern client (the browser, current Outlook), not an old mail app. **For admins:** 1. Check the failure reason first. It decides everything else. 2. Smart lockout on one user: find the source of the bad passwords. A phone or script with an old password keeps re-locking the account. If the source is one of your own servers, rule out a compromise before you assume a stale config: [hunting credential reuse after a web-server breach](https://brambrinkmeier.com/guides/hunt-credential-reuse-after-web-server-breach/). 3. Built-in block: Microsoft's unblock options are to add the IP to trusted named locations (only if you really own it), or move the client to modern authentication. 4. Spray pattern: use the second query to find any targeted account that got past the password. Reset those passwords and revoke sessions. 5. Block legacy authentication with Conditional Access. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Repeated password-grant (ROPC) token requests against a lab tenant; scenario: Repeated wrong passwords (smart lockout)). First line returned: > AADSTS50053: The account is locked, you've tried to sign in too many times with an incorrect user ID or password. Sign-in log row read: 2026-10-31. Lab-run rows naming this code (6; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Repeated wrong passwords (smart lockout) | 50053 | 50053 | AADSTS50053: The account is locked, you've tried to sign in too many times with an incorrect user ID or password. | | 2026-10-30 | Repeated wrong passwords (smart lockout) | 50053 | 50126 | AADSTS50126: Error validating credentials due to invalid username or password. | | 2026-10-30 | Repeated wrong passwords (smart lockout) | 50053 | 50053 | AADSTS50053: The account is locked, you've tried to sign in too many times with an incorrect user ID or password. | | 2026-10-30 | Repeated wrong passwords (smart lockout) | 50053 | 50053 | AADSTS50053: The account is locked, you've tried to sign in too many times with an incorrect user ID or password. | | 2026-10-30 | Repeated wrong passwords (smart lockout) | 50053 | 50053 | AADSTS50053: The account is locked, you've tried to sign in too many times with an incorrect user ID or password. | | 2026-10-31 | Repeated wrong passwords (smart lockout) | 50053 | 50053 | AADSTS50053: The account is locked, you've tried to sign in too many times with an incorrect user ID or password. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Protect user accounts from attacks with Microsoft Entra smart lockout](https://learn.microsoft.com/en-us/entra/identity/authentication/howto-password-smart-lockout) 3. [Remediate risks and unblock users (Microsoft Entra ID Protection)](https://learn.microsoft.com/en-us/entra/id-protection/howto-identity-protection-remediate-unblock) 4. [What is Conditional Access? (Microsoft Entra)](https://learn.microsoft.com/en-us/entra/identity/conditional-access/overview) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50057](https://brambrinkmeier.com/entra/aadsts/50057/), [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS530032](https://brambrinkmeier.com/entra/aadsts/530032/), [AADSTS50052](https://brambrinkmeier.com/entra/aadsts/50052/), [AADSTS50054](https://brambrinkmeier.com/entra/aadsts/50054/), [AADSTS50055](https://brambrinkmeier.com/entra/aadsts/50055/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50053: Account locked or sign-in blocked", https://brambrinkmeier.com/entra/aadsts/50053/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50054/ # AADSTS50054: Old password used for sign-in (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/50054/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50054.json **Short answer:** AADSTS50054 means a sign-in used an old password. Microsoft doesn't list the code. Its Entra Connect docs show it for the Connector account, often with AADSTS70002, and fix it with Add-ADSyncAADServiceAccount. For a normal user, our reading is that someone or something still holds a former password; treat repeated rows from unknown IPs like failed passwords. **Fix:** User: sign in with your current password and update it on every device and app that saved it. Admin (Entra Connect Connector account): on the sync server run `Add-ADSyncAADServiceAccount` with Global Administrator credentials. Other account from an unknown IP: reset the password, revoke sessions. | Field | Value | |---|---| | Code | AADSTS50054 | | Category | Credentials and lockout | | Type | Failure | | Attack signal | Medium: worth a look in context | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS50054 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS50054 (checked 30 October 2026). It lists 50053 and 50055 but skips 50054. Microsoft does quote it on another page. [Change the Microsoft Entra Connector account password](https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/how-to-connect-azureadaccount) lists it under *"errors reported by customers that were fixed by a credentials reset on the Microsoft Entra Connector account"*: > Event 6900 The server encountered an unexpected error while processing a password change notification: > AADSTS70002: Error validating credentials. AADSTS50054: Old password is used for authentication. > Event 659 Error while retrieving password policy sync configuration. Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException: AADSTS70002: Error validating credentials. AADSTS50054: Old password is used for authentication. The Connector account is the account Entra Connect Sync uses to talk to Entra ID. Microsoft calls it *"supposed to be service free"*. The page gives no cause beyond the message. Our reading: the sync server presented a password the account had before. The account's password changed in Entra ID, but the sync engine kept the old one. Microsoft documents 50054 only for that account. Whether Entra returns 50054 or [50126](https://brambrinkmeier.com/entra/aadsts/50126/) when a normal user types a former password is not documented. We haven't tested it. ## Is it an attack? For the Connector account, no. It is a sync configuration problem that Microsoft fixes with a reset. For any other account, it may matter, though Microsoft doesn't say so. The message implies the password was right once, so a device, an app or a person likely still holds a password the user used before. | Pattern | Likely meaning | |---|---| | The Connector account, from your Entra Connect server's IP | The sync engine has a stale password. Reset it as below. | | A user, from their usual devices, soon after a password change | A phone, mail client or saved credential still uses the old password. | | A user, from an IP or country they never use | Someone holds a former password, for example from an old leak. Investigate like a failed password from an unknown source. | | Many accounts from one IP | A list of old passwords being tried. Treat it like a password spray. | Only the first row comes from Microsoft's documentation. The other three are our reading. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 50054 is logged in. Check all three: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "50054" | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable ``` Who, from where, and with which app. The Connector account should show your sync server's IP: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "50054" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), IPs = make_set(IPAddress, 20) by UserPrincipalName, AppDisplayName, ClientAppUsed | sort by Rows desc ``` One IP with at least one 50054 row and failed passwords (50054 or 50126) for several accounts. The threshold of 3 is a starting point; tune it to your tenant: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType in ("50054", "50126") | summarize Accounts = dcount(UserPrincipalName), OldPasswordRows = countif(ResultType == "50054"), Rows = count() by IPAddress | where OldPasswordRows > 0 and Accounts >= 3 | sort by Accounts desc ``` ## How do I fix AADSTS50054? **For the user:** sign in with your current password. Update it on every device and app that saved the old one, such as phone mail apps. **For admins** (Entra Connect Connector account): Microsoft's fix is to reset the account's credentials on the sync server. On the Microsoft Entra Connect Sync server, open PowerShell: ```powershell $credential = Get-Credential Add-ADSyncAADServiceAccount -AADCredential $credential ``` Enter Global Administrator credentials when asked. Microsoft says the cmdlet *"resets the password for the service account and updates it both in Microsoft Entra ID and the sync engine."* After that, check that event 6900 or 659 stops. **For admins** (any other account): find the device or app from the second query. If the IP is unknown to the user, reset the password and revoke the user's sessions, as you would after a failed-password alert you can't explain. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. Lab-run rows naming this code (1; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Old password after an admin reset | 50054 / 50126 | error | Graph PATCH /users/{object-id}: HTTP 403 {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Change the Microsoft Entra Connector account password](https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/how-to-connect-azureadaccount) 3. [SigninLogs table reference (Azure Monitor)](https://docs.azure.cn/en-us/azure-monitor/reference/tables/SigninLogs) 4. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://docs.azure.cn/en-us/azure-monitor/reference/tables/AADNonInteractiveUserSignInLogs) ## Related codes [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50055](https://brambrinkmeier.com/entra/aadsts/50055/), [AADSTS50133](https://brambrinkmeier.com/entra/aadsts/50133/), [AADSTS50053](https://brambrinkmeier.com/entra/aadsts/50053/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50054: Old password used for sign-in (fix)", https://brambrinkmeier.com/entra/aadsts/50054/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50055/ # AADSTS50055: Password expired Canonical: https://brambrinkmeier.com/entra/aadsts/50055/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50055.json **Short answer:** AADSTS50055 means the user's password has expired, so Microsoft Entra ID ended the sign-in and offers a reset. For a real user it is routine. During a password spray it matters more: the wording implies the password entered was correct, just expired, so the attacker likely holds a valid credential. **Fix:** User: change your password when prompted, or ask your admin to reset it. Tell your admin if you weren't signing in at that time. Admin: for routine expiry, let the user reset. From a spray IP or unfamiliar location, reset the password yourself, revoke sessions and make sure MFA is registered. | Field | Value | |---|---| | Code | AADSTS50055 | | Microsoft name | InvalidPasswordExpiredPassword | | Category | Credentials and lockout | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1110.003](https://attack.mitre.org/techniques/T1110/003/) Brute Force: Password Spraying, [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-25) | | Last updated | 2026-10-30 | ## What does AADSTS50055 mean? Microsoft's description: > **InvalidPasswordExpiredPassword**: The password is expired. The user's password is expired, and therefore their login or session was ended. They will be offered the opportunity to reset it, or can ask an admin to reset it via Reset a user's password using Microsoft Entra ID. The user is sent to change the password before they can continue. ## Reproduced in the lab On 25 October 2026 an automated lab run sent a token request with the correct password for a test user who had to change the password at next sign-in. The run accepted 50055, 50144 or 50173 for this case; Entra returned `AADSTS50055` with this first line: > AADSTS50055: The password is expired. That confirms the code and its wording at the token endpoint. The same attempt in the lab tenant's sign-in log (Entra admin center, interactive user sign-ins), with identifiers left out: | Field | Value in the lab row | |---|---| | Status | Interrupted | | Sign-in error code | 50055 | | Additional details | The user's password is expired, and therefore their login or session was ended. They will be offered the opportunity to reset it, or may ask an admin to reset it. | | Authentication requirement | Single-factor authentication | | Conditional Access | Not Applied | | User type | Member | The test user had **must change password at next sign-in** set, not an expired password, yet the log row says the password is expired. In the logs the two look the same, so check the user's password policy and `lastPasswordChangeDateTime` before assuming a real expiry. The KQL below was run on the lab rows ([how](https://brambrinkmeier.com/methodology/)). The first query found both lab rows. The spray follow-up returned nothing as written, as expected on a lab sample this small; with the spray threshold lowered to 1 it found both rows. ## Is it an attack? Microsoft's password spray playbook lists *"50055 - Password expired"* among the sign-in events to review in a spray investigation. The playbook doesn't say why. The likely reason is an inference from the description: Entra tells the user the password is **expired**, not **wrong**. In practice that means the password entered was the right one. Compare 50126, where it was wrong. That changes how you read it: | Pattern | Likely meaning | |---|---| | A user on their normal device and IP, followed by a password change and success | Routine expiry. Benign. | | A 50055 from an IP that also produced many 50126 across different users | The spray **found a correct password** for this account. Treat it as a compromised credential. | | A 50055 from an unfamiliar country or hosting provider for a user who wasn't travelling | Someone else has this user's (old) password. | | 50055 followed by a success from the same unfamiliar IP | The worst case. The attacker may have changed the password and signed in. Check the audit log for the password change. | Expect `ConditionalAccessStatus` = `notApplied` on 50055 rows. Conditional Access only runs after the first factor succeeds, and the sign-in stopped at the password stage. ## How do I find it in my logs (KQL)? All 50055 rows, with the source, so you can spot ones that don't fit the user: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50055" | project TimeGenerated, UserPrincipalName, IPAddress, LocationDetails, AppDisplayName, ClientAppUsed, UserAgent | sort by TimeGenerated desc ``` 50055 from an IP that was also spraying. These are the rows that matter: ```kusto let sprayIPs = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50126" | summarize FailedUsers = dcount(UserPrincipalName) by IPAddress | where FailedUsers >= 10 | project IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50055" | where IPAddress in (sprayIPs) | project TimeGenerated, UserPrincipalName, IPAddress, ResultDescription, AppDisplayName, ClientAppUsed | sort by TimeGenerated asc ``` `ResultType` is a string column, so compare it with `"50055"`. ## How do Conditional Access and MFA affect it? - Conditional Access never ran on the 50055 row itself. It can still matter on the **next** step: if the attacker completes a password change and signs in, CA and MFA apply to that new sign-in. - That makes MFA the barrier that matters here. In practice, an attacker holding this password still has to pass whatever CA and MFA require on the follow-up sign-in. - `AuthenticationRequirement` on the 50055 row says nothing about your MFA setup. MFA was never reached. ## How do I fix AADSTS50055? **For the user:** change your password when prompted, or ask your admin to reset it. If you weren't trying to sign in at that time, tell your admin. **For admins:** 1. Routine expiry: let the user reset through the prompt or self-service password reset. 2. 50055 from a spray IP or an unfamiliar location: treat the old password as known to an attacker. Reset it yourself, revoke sessions (`Revoke-MgUserSignInSession`), and check whether that IP later got a success or an MFA prompt for the user. 3. Make sure the user has MFA registered, so a correct password alone isn't enough. ## Evidence Reproduced in a lab tenant on 2026-10-25 (ROPC token request against a lab tenant; scenario: Must change password at next sign-in). First line returned: > AADSTS50055: The password is expired. Sign-in log row read: 2026-10-30. KQL run against the exported lab rows: 2026-10-30. Lab-run rows naming this code (9; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-31 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-31 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 3. [Revoke user access in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/users/users-revoke-access) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50053](https://brambrinkmeier.com/entra/aadsts/50053/), [AADSTS50057](https://brambrinkmeier.com/entra/aadsts/50057/), [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS50052](https://brambrinkmeier.com/entra/aadsts/50052/), [AADSTS50054](https://brambrinkmeier.com/entra/aadsts/50054/), [AADSTS50125](https://brambrinkmeier.com/entra/aadsts/50125/), [AADSTS50133](https://brambrinkmeier.com/entra/aadsts/50133/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50055: Password expired", https://brambrinkmeier.com/entra/aadsts/50055/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50057/ # AADSTS50057 fix: the user account is disabled Canonical: https://brambrinkmeier.com/entra/aadsts/50057/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50057.json **Short answer:** AADSTS50057 means the user account is disabled in Microsoft Entra ID, so sign-in was refused. After an offboarding it is expected. The security signal is volume and source: many disabled accounts tried from one IP suggests a password spray working from an old user list. Hunt it with ResultType == "50057". **Fix:** Admin: if the account should be active, re-enable it (Entra admin center > Users > the user > Edit properties > Account enabled). Synced users: enable it in on-premises AD and sync. When disabling, also revoke sessions. User: ask your admin; this isn't a password problem. | Field | Value | |---|---| | Code | AADSTS50057 | | Microsoft name | UserDisabled | | Category | Credentials and lockout | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1110.003](https://attack.mitre.org/techniques/T1110/003/) Brute Force: Password Spraying, [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-25) | | Last updated | 2026-11-01 | ## What does AADSTS50057 mean? Microsoft's description: > **UserDisabled**: The user account is disabled. The user object in Active Directory backing this account has been disabled. An admin can re-enable this account through PowerShell The account exists but is switched off (`accountEnabled` = false), so Entra refuses the sign-in. Microsoft's wording mentions the Active Directory object, but the code is the same for a cloud-only account disabled in Entra ID. In hybrid tenants the disable is often done on-premises and synced up, so check both places when re-enabling. ## Reproduced in the lab On 25 October 2026 an automated lab run sent a token request with the correct password for a test user whose account was disabled. Entra returned `AADSTS50057` with this first line: > AADSTS50057: The user account is disabled. That confirms the code and its wording at the token endpoint. The same attempt in the lab tenant's sign-in log (Entra admin center, interactive user sign-ins), with identifiers left out: | Field | Value in the lab row | |---|---| | Status | Failure | | Sign-in error code | 50057 | | Failure reason | The user account is disabled. | | Authentication details | Password (password in the cloud), succeeded: false | | Authentication requirement | Single-factor authentication | | Conditional Access | Not Applied | | Client app | Mobile Apps and Desktop clients | | Resource | Microsoft Graph | | User type | Member | | Cross tenant access type | None | Two things on this page hold in the real row: Conditional Access shows **Not Applied**, because the sign-in stops before policies are evaluated, and the password check itself is recorded as not succeeded. The KQL below was run on the lab rows ([how](https://brambrinkmeier.com/methodology/)). The 14-day per-user query found both lab users. The spray query returned nothing as written, as expected for one disabled user per run; with its threshold lowered to 1 it found both source IPs. ## What is the quick fix? If the account should be active, re-enable it. If it was disabled on purpose (leaver, retired service account), nothing is broken and the sign-in attempts are the thing to clean up. - **Cloud-only user:** Entra admin center > Users > select the user > Edit properties > Account enabled. Or Graph: `Update-MgUser -UserId -AccountEnabled:$true`. - **Synced user:** enable the account in on-premises Active Directory, then run a sync. A cloud change is overwritten by the next sync. - **Leaver still trying:** find the device or app retrying and remove the stale profile or token. ## Is it an attack? Microsoft's password spray playbook lists *"50057 - User account was disabled"* among the sign-in events to review in a spray investigation. Most 50057 rows are still harmless. Read the pattern: | Pattern | Likely meaning | |---|---| | One recently offboarded user, from their old device or usual IP | A phone, mail client or synced app still trying with the old account. Benign, but clean it up. | | Rows in the non-interactive log for a leaver | An app still holding a token for that user and retrying silently. Revoke sessions. | | Many **different disabled accounts** from one IP | In practice, a spray working from an old or leaked user list. Disabled leavers and shared mailboxes are on those lists. (T1110.003) | | 50057 mixed with 50126 and 50034 from the same IP | The same spray hitting live, disabled and non-existent names. | | A disabled admin or service account tried from an unfamiliar IP | Someone has a credential for an account you retired. Find out where it came from. | | A 50057 account that suddenly shows a **success** | The account was re-enabled. Check the audit log for who did it. | Because the account is disabled, sign-in stops at the credential stage. Expect `ConditionalAccessStatus` = `notApplied` on these rows, as Conditional Access only runs after the first factor succeeds. ## How do I find it in my logs (KQL)? One IP trying several disabled accounts in a day: ```kusto SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50057" | summarize DisabledUsers = dcount(UserPrincipalName), Attempts = count(), Users = make_set(UserPrincipalName, 20), Clients = make_set(ClientAppUsed, 5) by IPAddress | where DisabledUsers >= 3 | sort by DisabledUsers desc ``` What is still trying to use disabled accounts, interactive and non-interactive together: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(14d) | where ResultType == "50057" | summarize Attempts = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), IPs = make_set(IPAddress, 10) by UserPrincipalName, AppDisplayName, ClientAppUsed, IsInteractive | sort by LastSeen desc ``` The threshold of 3 in the first query is a starting point. Tune it to how many leavers you normally see. ## How do Conditional Access and MFA affect it? - Conditional Access does not evaluate a 50057. The account is refused before CA runs. - `AuthenticationRequirement` on these rows says nothing about whether MFA is enforced in your tenant. MFA was never reached. - Disabling the account blocks **new** sign-ins. It does not by itself cut tokens an app already holds. Microsoft's revoke-access guidance pairs disabling the account with revoking sessions (`Revoke-MgUserSignInSession`) and already-issued access tokens keep working until they expire: by default 60 to 90 minutes. ## How do I fix AADSTS50057? **For the user:** if you still need access, ask your admin. A disabled account is an admin decision, not a password problem. Remove old work accounts from personal phones and mail apps. **For admins:** 1. If the account should be active, re-enable it. Microsoft's description says an admin can do this through PowerShell. In hybrid tenants, re-enable it in on-premises AD and let it sync. 2. If it is a leaver, find the device or app in the second query and remove the account from it. 3. When you disable an account for offboarding or an incident, also **revoke sessions**. 4. If the first query shows a spray, check whether the same IP produced any success, 50076/50074 or 53003 for **active** accounts. Those accounts had a correct password. ## Evidence Reproduced in a lab tenant on 2026-10-25 (ROPC token request against a lab tenant; scenario: Account disabled). First line returned: > AADSTS50057: The user account is disabled. Sign-in log row read: 2026-10-30. KQL run against the exported lab rows: 2026-10-30. Lab-run rows naming this code (9; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Account disabled | 50057 | 50057 | AADSTS50057: The user account is disabled. | | 2026-10-30 | Account disabled | 50057 | 50057 | AADSTS50057: The user account is disabled. | | 2026-10-30 | Account disabled | 50057 | 50057 | AADSTS50057: The user account is disabled. | | 2026-10-30 | Account disabled | 50057 | 50057 | AADSTS50057: The user account is disabled. | | 2026-10-30 | Account disabled | 50057 | 50057 | AADSTS50057: The user account is disabled. | | 2026-10-30 | Account disabled | 50057 | 50057 | AADSTS50057: The user account is disabled. | | 2026-10-30 | Account disabled | 50057 | 50057 | AADSTS50057: The user account is disabled. | | 2026-10-31 | Account disabled | 50057 | 50057 | AADSTS50057: The user account is disabled. | | 2026-10-31 | Account disabled | 50057 | 50057 | AADSTS50057: The user account is disabled. | ## Sources 1. [Access tokens in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens) 2. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 3. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 4. [Revoke user access in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/users/users-revoke-access) 5. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50053](https://brambrinkmeier.com/entra/aadsts/50053/), [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/), [AADSTS50055](https://brambrinkmeier.com/entra/aadsts/50055/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS50173](https://brambrinkmeier.com/entra/aadsts/50173/), [AADSTS135011](https://brambrinkmeier.com/entra/aadsts/135011/), [AADSTS500341](https://brambrinkmeier.com/entra/aadsts/500341/), [AADSTS500571](https://brambrinkmeier.com/entra/aadsts/500571/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50057 fix: the user account is disabled", https://brambrinkmeier.com/entra/aadsts/50057/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50058/ # AADSTS50058: Session information isn't sufficient for single sign-on Canonical: https://brambrinkmeier.com/entra/aadsts/50058/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50058.json **Short answer:** AADSTS50058 means an app tried to sign a user in silently (single sign-on, often with prompt=none) but there was no valid session to use. Microsoft calls it a common, expected error. It is one of the noisiest codes in most tenants and has low attack value. The app should fall back to an interactive sign-in. Filter it out of failure dashboards. **Fix:** Nothing to fix: this is an expected silent sign-in miss. User: sign in when the app asks. Developer: catch 50058, `login_required` and `interaction_required` from the silent call and fall back to an interactive sign-in. Admin: exclude 50058 from failure counts and spray rules. | Field | Value | |---|---| | Code | AADSTS50058 | | Microsoft name | UserInformationNotProvided | | Category | Tokens and sessions | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-24 | ## What does AADSTS50058 mean? Microsoft's description: > **UserInformationNotProvided**: Session information isn't sufficient for single-sign-on. This means that a user isn't signed in. This is a common error that's expected when a user is unauthenticated and hasn't yet signed in. If this error is encountered in an SSO context where the user has previously signed in, this means that the SSO session was either not found or invalid. This error might be returned to the application if prompt=none is specified. An app asked Microsoft Entra ID to sign the user in **without showing anything** and there was no usable session. The app is expected to catch this and show a normal sign-in. The usual trigger is `prompt=none`. Microsoft's authorization code flow reference says it *"ensures that the user isn't presented with any interactive prompt. If the request can't be completed silently by using single-sign on, the Microsoft identity platform returns an `interaction_required` error."* The OpenID Connect reference lists the causes: *"no signed-in user, the hinted user isn't signed in, or multiple users are signed in but no hint was provided."* Depending on the flow, the app may get 50058 itself or a protocol error such as `login_required` or `interaction_required`. Our reading is that these are the same event seen from two sides; the sign-in log records the AADSTS code. ## Is it an attack? No. Microsoft's description calls it *"a common error that's expected"*. Single-page apps and MSAL.js try silent sign-in first (`ssoSilent`, `acquireTokenSilent`) and Microsoft tells developers to *"handle any login_required or interaction_required errors with an interactive method"*. Every user who opens such an app without a session produces one. | Pattern | Likely meaning | |---|---| | 50058 for many users across Microsoft 365 and line-of-business apps | Normal silent SSO attempts. Benign noise. | | 50058 followed within seconds by a success for the same user and app | The app fell back to an interactive sign-in. Working as designed. | | A jump in 50058 for one browser type | Third-party cookie restrictions. Microsoft notes that *"ssoSilent requests will fail despite an active user session"* in some browsers. Our interpretation: that shows up as extra 50058 rows. | | 50058 for one user, repeating, with no success after | The app keeps retrying silently and never prompts. A bug in the app, not an attack. | There is no documented attack pattern for 50058. A silent request without a session gets nothing, so it gives an attacker nothing. Exclude it from failure-rate dashboards and spray detections, or it inflates them. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 50058 is logged in. Start by checking where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "50058" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Which apps generate the noise: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50058" | summarize Rows = count(), Users = dcount(UserPrincipalName) by AppDisplayName, ClientAppUsed | sort by Rows desc ``` Users who hit 50058 and never succeed afterwards on the same app the same day, a sign of an app that doesn't fall back to an interactive prompt: ```kusto let silentFails = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50058" | summarize FirstFail = min(TimeGenerated), Fails = count() by UserPrincipalName, AppId, AppDisplayName; let successes = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "0" | summarize LastSuccess = max(TimeGenerated) by UserPrincipalName, AppId; silentFails | join kind=leftouter successes on UserPrincipalName, AppId | where isnull(LastSuccess) or LastSuccess < FirstFail | project UserPrincipalName, AppDisplayName, Fails, FirstFail | sort by Fails desc ``` If the first query shows most 50058 in `AADNonInteractiveUserSignInLogs`, run the other two against that table, or both with `union`. Non-interactive rows are aggregated when application, user, IP address, status and resource match, so row counts there are not request counts. `ResultType` is a **string** column, so compare it with `"50058"`, not `50058`. ## How does Conditional Access affect it? - 50058 happens before Conditional Access. There is no authenticated user yet, so no policy is evaluated. - The interactive sign-in that follows goes through MFA and your Conditional Access policies as normal. - Don't confuse it with sign-in frequency. A refresh token refused by a sign-in frequency policy is logged as [70043](https://brambrinkmeier.com/entra/aadsts/70043/), a different code. ## How do I fix AADSTS50058? **For the user:** sign in when the app asks. If an app shows this error instead of a sign-in page, the app didn't fall back to an interactive sign-in; report it to whoever runs the app. **For developers:** treat 50058, `login_required` and `interaction_required` as *"show a sign-in"*, not as a failure. With MSAL.js, catch the error from the silent call and call `loginPopup`, `loginRedirect`, `acquireTokenPopup` or `acquireTokenRedirect`. Pass a `login_hint` with `prompt=none` when you know which user to expect. **For admins:** 1. Nothing is broken. Exclude `"50058"` from failure counts, password spray rules and alerting thresholds. 2. If the third query returns many users for one app, that app doesn't fall back to an interactive sign-in. Report it to its developer. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow) 3. [OpenID Connect on the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc) 4. [Prompt behavior with MSAL.js](https://learn.microsoft.com/en-us/entra/identity-platform/msal-js-prompt-behavior) 5. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50140](https://brambrinkmeier.com/entra/aadsts/50140/), [AADSTS70043](https://brambrinkmeier.com/entra/aadsts/70043/), [AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS50089](https://brambrinkmeier.com/entra/aadsts/50089/), [AADSTS50196](https://brambrinkmeier.com/entra/aadsts/50196/), [AADSTS54005](https://brambrinkmeier.com/entra/aadsts/54005/), [AADSTS70044](https://brambrinkmeier.com/entra/aadsts/70044/), [AADSTS75011](https://brambrinkmeier.com/entra/aadsts/75011/), [AADSTS165000](https://brambrinkmeier.com/entra/aadsts/165000/), [AADSTS700081](https://brambrinkmeier.com/entra/aadsts/700081/), [AADSTS9002341](https://brambrinkmeier.com/entra/aadsts/9002341/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50058: Session information isn't sufficient for single sign-on", https://brambrinkmeier.com/entra/aadsts/50058/ (CC BY 4.0), last updated 2026-10-24. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50059/ # AADSTS50059: No tenant-identifying information in the request (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/50059/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50059.json **Short answer:** AADSTS50059 means the request named no tenant and carried nothing Entra could use to work one out. It happens when a single-tenant app calls /common or /organizations without a user hint, for example in the device code flow. It is a configuration error with low attack value. Put your tenant ID or domain in the authority URL. **Fix:** Developer: replace `common` or `organizations` in the authority URL with your tenant ID or verified domain, and use the same tenant value on both the device code request and the token request. If the app really must serve several tenants, change Supported account types to multitenant instead. | Field | Value | |---|---| | Code | AADSTS50059 | | Microsoft name | MissingTenantRealmAndNoUserInformationProvided | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS50059 mean? Microsoft's description: > **MissingTenantRealmAndNoUserInformationProvided**: Tenant-identifying information wasn't found in either the request or implied by any provided credentials. The user can contact the tenant admin to help resolve the issue. Every request to the Microsoft identity platform has to resolve to one tenant before anything else can happen. The tenant comes from one of two places: the authority URL, or the credentials in the request. Microsoft's OpenID Connect reference lists what the URL can carry: | Value | Microsoft's description | |---|---| | `common` | Users with both a personal Microsoft account and a work or school account from Microsoft Entra ID can sign in to the application. | | `organizations` | Only users with work or school accounts from Microsoft Entra ID can sign in to the application. | | `consumers` | Only users with a personal Microsoft account can sign in to the application. | | Directory (tenant) ID or `contoso.onmicrosoft.com` | Only users from a specific Microsoft Entra tenant ... can sign in to the application. | `common` and `organizations` deliberately name no tenant. In an interactive browser sign-in that is fine, because the user types an address and Entra discovers the tenant from it. 50059 is what you get when there is no such step and nothing else in the request implies a tenant either: no username, no credential that belongs to a directory, no tenant in the URL. Three codes describe tenant problems and are easy to confuse: - [90002](https://brambrinkmeier.com/entra/aadsts/90002/) means a tenant *was* named and doesn't exist. - [900023](https://brambrinkmeier.com/entra/aadsts/900023/) means the tenant part of the URL isn't a valid tenant ID or domain at all, for example `undefined`. - 50059 means nothing was named, and nothing could be inferred. Microsoft's reference also lists **AADSTS50194** for an overlapping situation: *"Application '{appId}'({appName}) isn't configured as a multitenant application. Usage of the /common endpoint isn't supported for such applications created after '{time}'. Use a tenant-specific endpoint or configure the application to be multitenant."* That error names the app and the endpoint. 50059 is the earlier failure: Entra hadn't resolved a tenant, so it could not get as far as checking the app's supported account types. Our reading, from the lab result below: which of the two you get depends on how far the request gets before the tenant is needed. ## Reproduced in the lab On 30 October 2026 an automated lab run started a device code flow for a single-tenant app registration against `/common`, and separately against `/organizations`. Both returned the same code and message: > AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. Both rounds of the run reproduced it, four results in total. The run expected 90133, [700016](https://brambrinkmeier.com/entra/aadsts/700016/) or 50194, so the documented multitenant error is not what a device code request gives you here. The device code request carries only the client ID and the scope, which is exactly the shape 50059 describes: a request with no user and no tenant. Microsoft's device code flow page does allow the endpoint: *"`tenant` | Required | Can be `/common`, `/consumers`, or `/organizations`. It can also be the directory tenant that you want to request permission from in GUID or friendly name format."* Our reading: `/common` is accepted by the protocol and still fails for a single-tenant app, because the tenant can't be inferred from anything in that first call. No sign-in log row was captured. See [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? No. It is an app or script pointed at a tenant-agnostic endpoint that it can't use. | Pattern | Likely meaning | |---|---| | A CLI or device-code tool fails at the first step | The authority is `/common` or `/organizations` and the app registration is single-tenant. | | A library default was never changed | Many SDKs default to `common`. For a single-tenant app it has to be set to the tenant. | | Sample code copied from a multitenant tutorial | The sample's authority was right for its app registration, not for yours. | | A service-to-service call with no user | There is no user to infer a tenant from, so the URL must name the tenant. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 50059 lands in. Our reading, as with [90002](https://brambrinkmeier.com/entra/aadsts/90002/): the request did not resolve to a tenant, so your tenant most likely records nothing, and the error is visible to the caller rather than to you. Check anyway; this query is expected to return nothing or very little: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType in ("50059", "50194") or ResultSignature in ("50059", "50194") | summarize Rows = count(), Apps = make_set(AppId, 10), LastSeen = max(TimeGenerated) by SourceTable, ResultType ``` The query includes 50194 because that is the documented error for the same mistake once the app has been resolved, and because a row of either kind points at the same fix. What your logs can tell you is which tenant the failing app should be using. Find where it signs in successfully: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "0" | where AppId == "" | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, AppDisplayName, ResourceTenantId ``` `ResourceTenantId` carries the tenant of the resource in the sign-in. If this returns your tenant ID and the app's configuration says `common`, you have found the change to make. ## How do I fix AADSTS50059? **For the user:** nothing to fix on your device. Microsoft's own advice for this code is to contact the tenant admin. Pass on the name of the tool or app that failed. **For developers:** 1. Put the tenant in the authority URL: `https://login.microsoftonline.com//...`, or your verified domain instead of the GUID. 2. In the device code flow, use the same tenant value in both calls. Microsoft on the token request: *"`tenant` | Required | The same tenant or tenant alias used in the initial request."* 3. Only use `common` or `organizations` when the app registration really is multitenant and the flow has an interactive step where the user's address identifies the tenant. 4. Check the library default. An SDK that defaults to `common` needs the tenant set explicitly for a single-tenant app. **For admins:** 1. Give the app's owner your tenant ID, from **Entra ID** > **Overview** > **Properties**, or: ```powershell Connect-AzAccount Get-AzTenant ``` 2. If the app genuinely has to serve several tenants, change **Supported account types** on the registration to a multitenant value rather than leaving the endpoint as `common` against a single-tenant app. Microsoft's signInAudience page maps the portal choices to the manifest values: single tenant is `AzureADMyOrg`, multitenant is `AzureADMultipleOrgs`. 3. For a third-party product, send the vendor the tenant ID and tell them the integration must use a tenant-specific authority. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Device code request against a lab tenant; scenario: Device code on /common by a single-tenant app). First line returned: > AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. Lab-run rows naming this code (14; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and the OAuth 2.0 device authorization grant flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-device-code) 3. [OpenID Connect on the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc) 4. [Validation differences by supported account types (signInAudience)](https://learn.microsoft.com/en-us/entra/identity-platform/supported-accounts-validation) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS900023](https://brambrinkmeier.com/entra/aadsts/900023/), [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS70016](https://brambrinkmeier.com/entra/aadsts/70016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50059: No tenant-identifying information in the request (fix)", https://brambrinkmeier.com/entra/aadsts/50059/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50072/ # AADSTS50072: User needs to enroll for second factor authentication Canonical: https://brambrinkmeier.com/entra/aadsts/50072/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50072.json **Short answer:** AADSTS50072 is an interrupt: the user must enroll a second factor before the sign-in can finish. For a new user it is expected. Microsoft's password spray playbook lists it among the codes to monitor. From an unfamiliar IP it can mean someone with the correct password is being asked to set up MFA on the account. **Fix:** User: register your second factor when prompted, from a device and network you trust. If you didn't start this sign-in, stop and contact IT. Admin: issue new users a Temporary Access Pass if registration requires MFA. From an unfamiliar IP, check the account's registered methods. | Field | Value | |---|---| | Code | AADSTS50072 | | Microsoft name | UserStrongAuthEnrollmentRequiredInterrupt | | Category | Multifactor authentication | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts, [T1098.005](https://attack.mitre.org/techniques/T1098/005/) Account Manipulation: Device Registration | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-25 | ## What does AADSTS50072 mean? Microsoft's description: > **UserStrongAuthEnrollmentRequiredInterrupt**: User needs to enroll for second factor authentication (interactive). Microsoft's password spray playbook lists it among the Entra codes to monitor, worded as *"50072 - User prompted to provide MFA"*. Both texts point to the same moment: the password was accepted, MFA applies, and the sign-in is interrupted for the second factor. The error reference says the user still has to enroll one. The closely related [50079](https://brambrinkmeier.com/entra/aadsts/50079/) is the code the playbook describes as *"user needs to register security info"*. ## What is the quick fix? Usually nothing is broken. The user has to set up a second factor and then finish signing in. - **User:** follow the registration prompt from a device and network you trust. If you didn't start this sign-in, stop and contact IT. - **Admin, new users:** Microsoft's Conditional Access guidance says *"Administrators have to issue Temporary Access Pass credentials to new users so they can satisfy the requirements for multifactor authentication to register"* when registration itself requires MFA. Microsoft also notes *"Temporary Access Pass does not work for guest users."* - **Admin, unexpected rows:** if the user should already have methods, or the IP is unfamiliar, see the next section. ## Is it an attack? For a new hire or a user who just came into scope of an MFA policy, 50072 is the normal path into MFA. It matters when the sign-in isn't the user's: whoever completes enrollment from that session chooses the second factor. This is reasoning from how registration works, not a Microsoft statement. It is the same concern as on the [50079 page](https://brambrinkmeier.com/entra/aadsts/50079/). | Pattern | Likely meaning | |---|---| | 50072 for a new or newly in-scope user from a known office or home IP | Expected enrollment. Benign. | | 50072 from an IP that also produced **50126** failures against other users | A spray found a working password on an account without MFA. | | 50072 from an unfamiliar IP or country, then a success | Someone may have registered their own method. Check the account's methods. | | 50072 for a long-standing account that should already be registered | Check whether its methods were removed, and by whom. | These readings are based on Microsoft's description and the playbook listing. Microsoft doesn't publish a threat pattern for 50072 specifically. ## How do I find it in my logs (KQL)? 50072 per user and IP, with whether the same user and IP had a success afterwards: ```kusto let window = 7d; let interrupts = SigninLogs | where TimeGenerated > ago(window) | where ResultType == "50072" | summarize FirstInterrupt = min(TimeGenerated), Interrupts = count(), Apps = make_set(AppDisplayName, 5) by UserPrincipalName, IPAddress | extend Apps = strcat_array(Apps, ", "); let successes = SigninLogs | where TimeGenerated > ago(window) | where ResultType == "0" | project SuccessTime = TimeGenerated, UserPrincipalName, IPAddress; interrupts | join kind=leftouter successes on UserPrincipalName, IPAddress | summarize SuccessAfter = countif(SuccessTime > FirstInterrupt) by UserPrincipalName, IPAddress, FirstInterrupt, Interrupts, Apps | sort by FirstInterrupt desc ``` 50072 from IPs that were failing passwords against other users the same day: ```kusto let sprayIPs = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50126" | summarize FailedUsers = dcount(UserPrincipalName) by IPAddress | where FailedUsers >= 5 | project IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50072" | where IPAddress in (sprayIPs) | project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, ClientAppUsed, UserAgent | sort by TimeGenerated asc ``` The threshold of 5 failed users is a starting point, not a Microsoft number. `ResultType` is a **string** column, so compare it with `"50072"`, not `50072`. ## How do Conditional Access and MFA affect it? - 50072 means an MFA requirement applies and the account can't meet it yet. - Microsoft documents that an interrupted sign-in *"appears on the logs but shows **Not applied** for Conditional Access."* So `notApplied` on a 50072 row doesn't mean your policies are missing. - Conditional Access can protect the registration step itself with the **Register security information** user action. Microsoft's template *"requires users who are not on a trusted network to do multifactor authentication"* to register. ## How do I fix AADSTS50072? **For the user:** register your second factor when prompted, from a device and network you trust. **For admins:** 1. For new users, issue a Temporary Access Pass if your registration policy requires MFA. 2. For every 50072 from an IP the user doesn't use, check the account's registered methods and remove any you can't tie to the user. 3. Protect security info registration with a Conditional Access policy on the **Register security information** user action. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. Lab-run rows naming this code (9; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-31 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-31 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 3. [Interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-interactive-sign-ins) 4. [Require MFA for security info registration (Conditional Access)](https://learn.microsoft.com/en-us/entra/identity/conditional-access/policy-all-users-security-info-registration) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50079](https://brambrinkmeier.com/entra/aadsts/50079/), [AADSTS50074](https://brambrinkmeier.com/entra/aadsts/50074/), [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50072: User needs to enroll for second factor authentication", https://brambrinkmeier.com/entra/aadsts/50072/ (CC BY 4.0), last updated 2026-10-25. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50074/ # AADSTS50074: strong authentication is required (MFA) Canonical: https://brambrinkmeier.com/entra/aadsts/50074/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50074.json **Short answer:** AADSTS50074 means MFA was required and the user did not pass the challenge. The first factor (usually the password) had already succeeded. One or two are normal. Many for one user in a short window from an unfamiliar IP is the MFA fatigue pattern: someone with the correct password is pushing prompts and waiting for an approval. **Fix:** User: approve the prompt if you started the sign-in, check your phone has signal and Authenticator is up to date, then retry. If you didn't start it, deny and report it. Admin: for a burst from an IP the user doesn't use, reset the password and revoke sessions if a success followed. | Field | Value | |---|---| | Code | AADSTS50074 | | Microsoft name | UserStrongAuthClientAuthNRequiredInterrupt | | Category | Multifactor authentication | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1621](https://attack.mitre.org/techniques/T1621/) Multi-Factor Authentication Request Generation, [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS50074 mean? Microsoft's description: > **UserStrongAuthClientAuthNRequiredInterrupt**: Strong authentication is required and the user did not pass the MFA challenge. Microsoft's password spray playbook lists it as *"50074 - MFA required"*. Either way the order of events is the same: the password was accepted, then the MFA step did not complete. ## What is the quick fix? Usually nothing is broken. In practice this row often appears when MFA is first requested, so the user just needs to finish the prompt. - **User:** approve the prompt, check the phone has a signal and the Authenticator app is up to date, and retry. If no method is registered, register one at the Security info page. - **Admin:** check the user's registered methods and the Conditional Access policy that requires MFA on the sign-in's Conditional Access tab. - **Repeated rows from an unfamiliar IP:** see the next section. ## Is it an attack? A single 50074 often just means the sign-in reached the MFA step. It can be logged as an interrupt row before the user finishes MFA, so one row on its own says little. It can also be a user who dismissed a prompt, picked up the wrong phone, or let it time out. **The signal is repetition, and where it comes from.** | Pattern | Likely meaning | |---|---| | One 50074, then `0` from the same IP and device | The user retried and passed MFA. Benign. | | Several 50074 for **one user** in minutes, from an IP or country the user doesn't use | **MFA fatigue** (T1621). The attacker has the password and is generating prompts. | | 50074 burst followed by `0` from the **same unfamiliar IP** | **The user approved a prompt they didn't start.** Treat as account takeover. | | 50074 from an IP that also produced many **50126** failures | The spray found a correct password and is now stuck at MFA. | | 50074 alongside **500121** for the same user | Same picture. See [500121](https://brambrinkmeier.com/entra/aadsts/500121/). | The playbook's instruction applies directly: *"record successful passwords but failed MFA responses, as this activity indicates that the attacker is getting the password but not passing MFA."* ## How do I find it in my logs (KQL)? Users with repeated 50074 from one IP within an hour: ```kusto SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50074" | summarize Prompts = count(), FirstSeen = min(CreatedDateTime), LastSeen = max(CreatedDateTime), Apps = make_set(AppDisplayName, 5) by UserPrincipalName, IPAddress, bin(CreatedDateTime, 1h) | where Prompts >= 3 | sort by Prompts desc ``` The threshold of 3 is a starting point, not a Microsoft number. Tune it against your own baseline. The hourly bins use `CreatedDateTime`, not `TimeGenerated`. Microsoft's interactive sign-ins page: *"The `TimeGenerated` field is the time the entry was received and published by Log Analytics, not the time the sign-in occurred. The `CreatedDateTime` field in the logs shows the time the sign-in occurred."* The `TimeGenerated > ago(1d)` filter is fine for picking the time range; for burst windows, use the sign-in time. What happened at the MFA step. `AuthenticationDetails` is a **string** column holding a JSON array, so parse it first: ```kusto SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50074" | mv-expand Step = parse_json(AuthenticationDetails) | extend Method = tostring(Step.authenticationMethod), StepResult = tostring(Step.authenticationStepResultDetail), Succeeded = tobool(Step.succeeded) | summarize Steps = count() by UserPrincipalName, IPAddress, Method, StepResult, Succeeded | sort by Steps desc ``` The field names inside `AuthenticationDetails` follow the Microsoft Graph `authenticationDetail` object. Check them against a row in your own workspace before relying on this query. Don't use `MfaDetail`; Microsoft marks that column as deprecated. ## How do Conditional Access and MFA affect it? - 50074 is the MFA requirement doing its job. Whatever required MFA (a Conditional Access grant, per-user MFA, security defaults) stopped a sign-in whose first factor (usually the password) had succeeded. - Microsoft documents that an interrupted sign-in *"appears on the logs but shows **Not applied** for Conditional Access."* Don't conclude from that column that no policy applied. - Push approval without context is what fatigue attacks rely on. Microsoft enforced number matching for Microsoft Authenticator push in 2023, so the plain "tap Approve" path mostly remains in third-party or NPS-extension MFA. Phishing-resistant methods (FIDO2, passkeys, Windows Hello for Business) remove the push entirely. The [MFA fatigue guide](https://brambrinkmeier.com/guides/detect-mfa-fatigue-entra-id/) walks through the investigation. ## How do I fix AADSTS50074? **For the user:** if you didn't start the sign-in, deny the prompt and report it. That prompt means someone has your password. **For admins:** 1. If the 50074 burst came from an IP the user doesn't use, reset the password. The attacker already has it. 2. Check for a later `0` from the same IP. If there is one, revoke sessions (`Revoke-MgUserSignInSession`) and review what the session accessed. 3. Move users off plain push approval toward phishing-resistant methods. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 3. [Interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-interactive-sign-ins) 4. [Revoke user access in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/users/users-revoke-access) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS500121](https://brambrinkmeier.com/entra/aadsts/500121/), [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS50079](https://brambrinkmeier.com/entra/aadsts/50079/), [AADSTS50072](https://brambrinkmeier.com/entra/aadsts/50072/), [AADSTS50140](https://brambrinkmeier.com/entra/aadsts/50140/), [AADSTS50158](https://brambrinkmeier.com/entra/aadsts/50158/), [AADSTS75011](https://brambrinkmeier.com/entra/aadsts/75011/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50074: strong authentication is required (MFA)", https://brambrinkmeier.com/entra/aadsts/50074/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50076/ # AADSTS50076: MFA required to access the resource Canonical: https://brambrinkmeier.com/entra/aadsts/50076/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50076.json **Short answer:** AADSTS50076 means the password was accepted but the sign-in now needs multifactor authentication, usually because of a Conditional Access policy, per-user MFA, or a new location. It is an expected interrupt. The signal is who reached it: a 50076 from an IP that was just failing passwords means an attacker has a working password. **Fix:** User: complete the MFA prompt. If the app keeps failing silently, sign out and sign in again. Admin: if the 50076 came from a spray IP, reset the password and revoke sessions. Developer: a background token refresh can't satisfy MFA, so request the token interactively. | Field | Value | |---|---| | Code | AADSTS50076 | | Microsoft name | UserStrongAuthClientAuthNRequired | | Category | Multifactor authentication | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts, [T1110.003](https://attack.mitre.org/techniques/T1110/003/) Brute Force: Password Spraying | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS50076 mean? Microsoft's description: > **UserStrongAuthClientAuthNRequired**: Due to a configuration change made by the admin such as a Conditional Access policy, per-user enforcement, or because you moved to a new location, the user must use multifactor authentication to access the resource. Retry with a new authorize request for the resource. The first factor passed. Entra ID stopped the sign-in to ask for a second factor. In an interactive browser sign-in the user normally sees the MFA prompt and a follow-up request completes. That is why most 50076 rows are not failures in any practical sense. ## Is it an attack? See the [comparison of the codes behind "asked to sign in again"](https://brambrinkmeier.com/guides/why-user-asked-to-sign-in-again-entra-id/) (70043, 700082, 50173, 50133, 50076). Usually not. Every MFA prompt in your tenant can produce one. **The value of 50076 is that it shows the first factor (usually the password) succeeded.** | Pattern | Likely meaning | |---|---| | 50076, then `0` (success) from the same IP and device within minutes | The user completed MFA. Benign. | | 50076 from an IP that produced many **50126** failures | **The spray found a working password.** MFA is now the only barrier. | | 50076 followed by repeated **50074** or **500121** for the same user | Someone with the password is pushing MFA prompts the user is not approving. See [50074](https://brambrinkmeier.com/entra/aadsts/50074/). | | 50076 in `AADNonInteractiveUserSignInLogs` from an IP the user never signed in from | A refresh token being used where a new MFA requirement applies. Could be a user on a new network, could be a replayed token. This reading is reasoning from the mechanism, not a Microsoft statement. | Microsoft's password spray playbook tells responders to *"record successful passwords but failed MFA responses, as this activity indicates that the attacker is getting the password but not passing MFA."* A 50076 from an attacker IP is that record. On these rows `AuthenticationRequirement` is `multiFactorAuthentication`. Microsoft documents that a sign-in where primary authentication succeeds and MFA is required carries that value. ## How do I find it in my logs (KQL)? Users who hit the MFA step from an IP that was failing passwords for them earlier the same day: ```kusto let failedPw = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50126" | summarize Failures = count(), FirstFail = min(TimeGenerated) by UserPrincipalName, IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50076" | join kind=inner failedPw on UserPrincipalName, IPAddress | where TimeGenerated > FirstFail | project TimeGenerated, UserPrincipalName, IPAddress, Failures, AppDisplayName, ClientAppUsed, AuthenticationRequirement, UserAgent | sort by TimeGenerated asc ``` Non-interactive 50076 from IPs the user has had no successful sign-in from, in either table, in the last 14 days. Mobile devices change IPs often, so expect benign rows and check the country and user agent before escalating: ```kusto let knownIPs = union (SigninLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType), (AADNonInteractiveUserSignInLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType) | where TimeGenerated > ago(14d) | where ResultType == "0" | distinct UserPrincipalName, IPAddress; AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "50076" | join kind=leftanti knownIPs on UserPrincipalName, IPAddress | summarize Events = count(), Apps = make_set(AppDisplayName, 5), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by UserPrincipalName, IPAddress | sort by Events desc ``` `ResultType` is a **string** column, so compare it with `"50076"`. Non-interactive rows are aggregated by Microsoft when application, user, IP, status and resource match, so `Events` counts log rows, not individual token requests. ## How do Conditional Access and MFA affect it? - 50076 is what a Conditional Access MFA grant, per-user MFA or a location change looks like at the moment it fires. The control is working. - Microsoft's interactive sign-ins documentation says an interrupted sign-in *"appears on the logs but shows **Not applied** for Conditional Access."* Don't read `notApplied` on a 50076 row as proof that no policy targets the user. Look at the follow-up sign-in. - If MFA is satisfied by push approval, the password alone gets an attacker to the point where they can generate prompts. Number matching (enforced for Microsoft Authenticator since 2023) and phishing-resistant methods reduce what they can do from there. See the [MFA fatigue guide](https://brambrinkmeier.com/guides/detect-mfa-fatigue-entra-id/). ## How do I fix AADSTS50076? **For the user:** complete the MFA prompt. If the app keeps failing silently, sign out and sign in again so it makes a new interactive request, which is what Microsoft's text asks for ("Retry with a new authorize request"). **For admins:** 1. If the 50076 came from an IP you associate with a spray, treat the password as compromised. Reset it and revoke sessions (`Revoke-MgUserSignInSession`, or **Revoke sessions** on the user in the admin center). 2. Check whether the same IP later produced a `0` for that user. If it did, this is a compromised account, not an attempt. 3. For developers: a daemon or background token refresh can't satisfy MFA. Request the token interactively. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. Lab-run rows naming this code (12; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Refresh token after the admin revoked sessions | 50173 / 700082 / 50076 | 50173 | AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. The gran | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-31 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-31 | Refresh token after the admin revoked sessions | 50173 / 700082 / 50076 | 50173 | AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. The gran | | 2026-10-31 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-31 | Refresh token after the admin revoked sessions | 50173 / 700082 / 50076 | 50173 | AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. The gran | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 3. [Sign-in log activity details](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-in-log-activity-details) 4. [Interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-interactive-sign-ins) 5. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 6. [Revoke user access in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/users/users-revoke-access) 7. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50074](https://brambrinkmeier.com/entra/aadsts/50074/), [AADSTS500121](https://brambrinkmeier.com/entra/aadsts/500121/), [AADSTS50079](https://brambrinkmeier.com/entra/aadsts/50079/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS50158](https://brambrinkmeier.com/entra/aadsts/50158/), [AADSTS50055](https://brambrinkmeier.com/entra/aadsts/50055/), [AADSTS50072](https://brambrinkmeier.com/entra/aadsts/50072/), [AADSTS50125](https://brambrinkmeier.com/entra/aadsts/50125/), [AADSTS50140](https://brambrinkmeier.com/entra/aadsts/50140/), [AADSTS70043](https://brambrinkmeier.com/entra/aadsts/70043/), [AADSTS75011](https://brambrinkmeier.com/entra/aadsts/75011/), [AADSTS90072](https://brambrinkmeier.com/entra/aadsts/90072/), [AADSTS530032](https://brambrinkmeier.com/entra/aadsts/530032/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50076: MFA required to access the resource", https://brambrinkmeier.com/entra/aadsts/50076/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50079/ # AADSTS50079: User must register for MFA Canonical: https://brambrinkmeier.com/entra/aadsts/50079/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50079.json **Short answer:** AADSTS50079 means MFA is required but the user has not registered security info yet, so Entra ID sends them to register. For a real new user it is expected. If the sign-in came from an attacker IP, the attacker has a correct password and is being invited to register their own MFA method on the account. **Fix:** User: register your MFA method from a device and network you trust. If you didn't expect the prompt, stop and contact IT. Admin: for a 50079 from an IP the user doesn't use, check the registered methods and remove any you can't tie to the user. Protect registration with Conditional Access. | Field | Value | |---|---| | Code | AADSTS50079 | | Microsoft name | UserStrongAuthEnrollmentRequired | | Category | Multifactor authentication | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | High: often seen in attacks | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts, [T1098.005](https://attack.mitre.org/techniques/T1098/005/) Account Manipulation: Device Registration | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS50079 mean? Microsoft's description: > **UserStrongAuthEnrollmentRequired**: Due to a configuration change made by the admin such as a Conditional Access policy, per-user enforcement, or because the user moved to a new location, the user is required to use multifactor authentication. Either a managed user needs to register security info to complete multifactor authentication, or a federated user needs to get the multifactor claim from the federated identity provider. Microsoft's password spray playbook lists it as *"50079 - user needs to register security info"*. The password was accepted. The account has no MFA method, so the next screen is registration. ## Is it an attack? For a new hire, a freshly enabled policy, or a user who never registered, 50079 is the normal path into MFA. **It becomes the most important row in an investigation when the sign-in is not the user's.** Whoever completes registration from that session chooses the MFA method. If an attacker with a sprayed or phished password lands on an unregistered account, 50079 is the moment they can add their own authenticator app or phone, and from then on MFA protects the attacker, not the user. This is reasoning from how registration works, not a Microsoft statement, but it is why the playbook lists the code. | Pattern | Likely meaning | |---|---| | 50079 for a new or newly in-scope user, from a known office or home IP | Expected registration. Benign. | | 50079 from an IP that also produced **50126** failures against other users | A spray found a working password on an account with no MFA. | | 50079 from an unfamiliar IP or country, then a security info registration event, then `0` | **Likely account takeover with attacker-registered MFA** (T1098.005). | | 50079 for a long-standing account that should already be registered | Check whether its methods were deleted, and by whom. | ## How do I find it in my logs (KQL)? 50079 from IPs that were failing passwords against other users the same day: ```kusto let sprayIPs = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50126" | summarize FailedUsers = dcount(UserPrincipalName) by IPAddress | where FailedUsers >= 5 | project IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50079" | where IPAddress in (sprayIPs) | project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, ClientAppUsed, UserAgent | sort by TimeGenerated asc ``` 50079 followed within an hour by a security info registration in `AuditLogs` for the same user: ```kusto let interrupts = SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50079" | project InterruptTime = TimeGenerated, UserPrincipalName = tolower(UserPrincipalName), SigninIP = IPAddress; AuditLogs | where TimeGenerated > ago(7d) | where OperationName has "security info" | extend UserPrincipalName = tolower(tostring(InitiatedBy.user.userPrincipalName)), AuditIP = tostring(InitiatedBy.user.ipAddress) | join kind=inner interrupts on UserPrincipalName | where TimeGenerated between (InterruptTime .. (InterruptTime + 1h)) | project InterruptTime, RegisteredAt = TimeGenerated, UserPrincipalName, SigninIP, AuditIP, OperationName, Result | sort by RegisteredAt desc ``` Verify the exact `OperationName` values for security info registration in your own workspace before relying on the `has "security info"` filter, and check that `InitiatedBy` carries the user and IP fields for those events. The threshold of 5 failed users is a starting point, not a Microsoft number. ## How do Conditional Access and MFA affect it? - 50079 means an MFA requirement applies but the account can't meet it yet. The requirement is not the problem. Who gets to satisfy it first is. - Microsoft documents that an interrupted sign-in *"appears on the logs but shows **Not applied** for Conditional Access."* - Conditional Access can protect the registration step itself, for example by only allowing security info registration from trusted locations or compliant devices. When a policy blocks registration, users see **53010** instead. - Federated users get this code when the federated identity provider didn't send the MFA claim. In that case registration in Entra ID is not the fix. ## How do I fix AADSTS50079? **For the user:** register your MFA method from a device and network you trust. If you get a registration prompt you didn't expect, stop and contact IT. **For admins:** 1. For every 50079 from an IP the user doesn't use, check the account's registered methods. Remove any you can't tie to the user. 2. If an attacker registered a method, reset the password, remove the method, and revoke sessions (`Revoke-MgUserSignInSession`). 3. Protect security info registration with Conditional Access so it can only happen from trusted locations or devices. 4. Don't leave accounts unregistered for long. An account with a password and no MFA method is registered by whoever signs in first. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. Lab-run rows naming this code (9; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-31 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-31 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 3. [Interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-interactive-sign-ins) 4. [Revoke user access in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/users/users-revoke-access) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS50072](https://brambrinkmeier.com/entra/aadsts/50072/), [AADSTS50125](https://brambrinkmeier.com/entra/aadsts/50125/), [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50074](https://brambrinkmeier.com/entra/aadsts/50074/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS90072](https://brambrinkmeier.com/entra/aadsts/90072/), [AADSTS500121](https://brambrinkmeier.com/entra/aadsts/500121/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50079: User must register for MFA", https://brambrinkmeier.com/entra/aadsts/50079/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50089/ # AADSTS50089: Flow token expired, sign in again (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/50089/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50089.json **Short answer:** AADSTS50089 means a sign-in failed because a token that was part of the sign-in had expired. Microsoft calls it expected: auth codes, refresh tokens and sessions expire or get revoked, and the app asks the user to sign in again. It has low attack value. Filter it out of failure dashboards and look only at users who can't get past it. **Fix:** Nothing to fix: the token expired as designed. User: sign in again. If it keeps happening, close the app or tab and start a fresh sign-in. Developer: treat 50089 as 'start a new sign-in' and redeem auth codes immediately. Admin: exclude 50089 from failure counts and spray rules. | Field | Value | |---|---| | Code | AADSTS50089 | | Category | Tokens and sessions | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS50089 mean? Microsoft's description: > Authentication failed due to flow token expired. Expected - auth codes, refresh tokens, and sessions expire over time or are revoked by the user or an admin. The app will request a new login from the user. The reference table gives this code no PascalCase name. Microsoft doesn't define "flow token" anywhere we could find. Our reading is that it refers to the state Entra keeps for a sign-in in progress, so a sign-in page left open too long before the user finishes would produce 50089. The description itself names three things that expire: auth codes, refresh tokens and sessions. Some documented lifetimes: - **Authorization codes** are short lived. The authorization code flow reference: *"Typically, they expire after about 1 minute."* - **Refresh tokens** have a default Max Inactive Time of 90 days. - **Session tokens**: *"Non-persistent session tokens have a Max Inactive Time of 24 hours; persistent session tokens have a Max Inactive Time of 90 days."* Several close relatives cover specific cases of "your old token or session no longer counts": - **[50133](https://brambrinkmeier.com/entra/aadsts/50133/)**: the session is invalid after a password change or expiry. - **[50173](https://brambrinkmeier.com/entra/aadsts/50173/)**: the grant was revoked, for example after a password reset. - **[70043](https://brambrinkmeier.com/entra/aadsts/70043/)**: a Conditional Access sign-in frequency policy refused the refresh token. For a comparison of the codes behind repeated sign-in prompts, see [why a user is asked to sign in again](https://brambrinkmeier.com/guides/why-user-asked-to-sign-in-again-entra-id/). ## Is it an attack? No. Microsoft's description starts with *"Expected"*. The sign-in fails, nothing is issued, and the app starts over. | Pattern | Likely meaning | |---|---| | A few 50089 rows per user, each followed by a success | A token or sign-in step expired and the user signed in again. Benign. | | 50089 for many users of one app, all at the same time of day | Our interpretation: users who leave the sign-in page or app open overnight and continue the next morning. Benign. | | 50089 for one user, repeating several times a day, often with no success after | Something on that device keeps presenting an expired token or session. Clear the app's cached sign-in or browser state. | | 50089 together with 50133 or 50173 for the same user | A password change or revocation is working its way through the user's sessions. Benign if you know about the change. | There is no documented attack pattern for 50089. An expired token gets the sender nothing. Keep it out of password spray detections and failure-rate thresholds. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 50089 is logged in. Start by checking where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "50089" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Which apps and client types produce it: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "50089" | summarize Rows = count(), Users = dcount(UserPrincipalName) by AppDisplayName, ClientAppUsed | sort by Rows desc ``` Users who hit 50089 again and again without a success afterwards on the same app the same day. These are the ones worth a support ticket: ```kusto let expired = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "50089" | summarize FirstFail = min(TimeGenerated), Fails = count() by UserPrincipalName, AppId, AppDisplayName; let successes = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "0" | summarize LastSuccess = max(TimeGenerated) by UserPrincipalName, AppId; expired | join kind=leftouter successes on UserPrincipalName, AppId | where isnull(LastSuccess) or LastSuccess < FirstFail | where Fails >= 5 | project UserPrincipalName, AppDisplayName, Fails, FirstFail | sort by Fails desc ``` The threshold of 5 is a starting point; tune it to your tenant. Non-interactive rows are aggregated when application, user, IP address, status and resource match, so `Fails` counts rows there, not requests. `ResultType` is a **string** column, so compare it with `"50089"`, not `50089`. ## How does Conditional Access affect it? - 50089 is not a Conditional Access block. No policy causes it directly. - Session lifetime is now controlled with Conditional Access. Microsoft: refresh and session token lifetimes *"are no longer configurable through token lifetime policies"* and *"To control how frequently users are required to sign in, use Conditional Access sign-in frequency instead."* - A sign-in frequency policy that refuses a refresh token shows up as [70043](https://brambrinkmeier.com/entra/aadsts/70043/), not 50089. If users complain about frequent prompts, check for 70043 first. - Microsoft warns that combining **Remember MFA on trusted devices** with sign-in frequency *"might prompt users unexpectedly."* ## How do I fix AADSTS50089? **For the user:** sign in again. If it keeps happening, close the app or browser tab completely and start a fresh sign-in instead of continuing an old one. **For developers:** treat 50089 as "start a new sign-in", not as a fatal error. Microsoft says *"The app will request a new login from the user."* Redeem authorization codes immediately; they typically expire after about a minute. Don't build logic on the code number itself. Microsoft notes that *"Apps that take a dependency on text or error code numbers will be broken over time."* React to the OAuth `error` value instead. **For admins:** 1. Nothing is broken. Exclude `"50089"` from failure counts and spray detections. 2. Use the third query for users stuck in a loop. Clear the app's cached sign-in on their device or browser. 3. If many users get unexpected sign-in prompts, review your Conditional Access session controls (sign-in frequency, persistent browser session) and turn off **Remember MFA on trusted devices** if you use sign-in frequency. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Configurable token lifetimes in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes) 3. [Configure adaptive session lifetime policies](https://learn.microsoft.com/en-us/entra/identity/conditional-access/howto-conditional-access-session-lifetime) 4. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow) 5. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) ## Related codes [AADSTS50133](https://brambrinkmeier.com/entra/aadsts/50133/), [AADSTS50173](https://brambrinkmeier.com/entra/aadsts/50173/), [AADSTS70043](https://brambrinkmeier.com/entra/aadsts/70043/), [AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50089: Flow token expired, sign in again (fix)", https://brambrinkmeier.com/entra/aadsts/50089/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50097/ # AADSTS50097 fix: device authentication is required Canonical: https://brambrinkmeier.com/entra/aadsts/50097/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50097.json **Short answer:** AADSTS50097 means Microsoft Entra ID asked the client to prove the device's identity because a device-based Conditional Access policy applies. Managed clients answer it silently. Clients that can't prove a device identity stop here. A spike for one user from a new IP can mean a valid credential is being used on an unmanaged device. **Fix:** User: sign in from a managed work device, with a supported browser (Edge with the work profile, or Chrome with the Windows Accounts extension) or the broker app (Company Portal, Authenticator). Admin: if no success followed and the IP is new, reset the password and revoke sessions. | Field | Value | |---|---| | Code | AADSTS50097 | | Microsoft name | DeviceAuthenticationRequired | | Category | Devices | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS50097 mean? Microsoft's description: > **DeviceAuthenticationRequired**: Device authentication is required. The MSAL.NET documentation explains when it happens: > This error happens when a conditional access policy is applied to the resource you are accessing, which required that the device from which the token is acquired be managed by the organization, and that MSAL.NET proves this identity. So 50097 is a request for proof, not a final verdict. A client on a managed device that can present the device identity continues. A client that can't present it stops here. ## What is the quick fix? Check these first: - **The sign-in came from a device your organization does not manage.** Use a managed, Entra joined, hybrid joined or registered device, as the policy requires. - **Browser without device sign-in support.** Chrome needs the Microsoft Single Sign On extension (Windows Accounts) on Windows, and Edge needs to be signed in with the work profile. Firefox needs Windows SSO enabled. Check Microsoft's documentation for your browser version, as support changes. - **macOS or mobile without the broker.** Company Portal and the Microsoft Enterprise SSO plug-in (macOS), or the Authenticator or Company Portal app (iOS and Android), are what present the device identity. - **The device is not registered or its registration is stale.** Check the device in the Entra admin center and in `dsregcmd /status` on Windows. - **Custom app or script.** The client has to use a broker-aware MSAL flow, see the sources. ## Is it an attack? Mostly not. 50097 is often a step inside a normal sign-in on a managed device, or a client app (custom MSAL code, a script, a non-broker client) that doesn't support device authentication. The security reading: a device-based policy is asking the caller to prove it is one of your devices. **An attacker's machine can't.** | Pattern | Likely meaning | |---|---| | 50097 followed by a success for the same user, device and app within seconds | Normal device-authentication step. Benign. | | Repeated 50097 from one internal app or script | The client doesn't support device authentication. Developer or configuration issue. | | 50097 for one user from a new IP, no device ID, no success afterwards | **A valid credential on an unmanaged device.** Investigate. | | 50097 alongside 53000 or 53001 for the same user and IP | Same story from a different angle: device policy is stopping a working credential. | These readings are based on what Microsoft says the code means. Microsoft doesn't publish a threat pattern for 50097 specifically. ## How do I find it in my logs (KQL)? 50097 that never turned into a success for the same user and IP within ten minutes: ```kusto let window = 10m; let challenges = SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50097" | project ChallengeTime = TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, DeviceId = tostring(DeviceDetail.deviceId), OS = tostring(DeviceDetail.operatingSystem), ClientAppUsed, UserAgent; let successes = SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "0" | project SuccessTime = TimeGenerated, UserPrincipalName, IPAddress; challenges | join kind=leftouter successes on UserPrincipalName, IPAddress | extend Followed = SuccessTime between (ChallengeTime .. (ChallengeTime + window)) | summarize Completed = countif(Followed) by ChallengeTime, UserPrincipalName, IPAddress, AppDisplayName, DeviceId, OS, ClientAppUsed, UserAgent | where Completed == 0 | sort by ChallengeTime desc ``` Volume per user and IP, to spot a new source: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50097" | summarize Attempts = count(), Apps = make_set(AppDisplayName, 5), DeviceIds = make_set(tostring(DeviceDetail.deviceId), 5), FirstSeen = min(TimeGenerated) by UserPrincipalName, IPAddress | sort by Attempts desc ``` On `AADNonInteractiveUserSignInLogs`, `DeviceDetail` is a **string** column: use `parse_json(DeviceDetail).deviceId`. The `DeviceDetail` property names follow the Microsoft Graph `signIn` device detail object; check them against one row in your own workspace first. ## How does Conditional Access affect it? - 50097 comes from a Conditional Access policy that depends on the device (for example a compliant or hybrid joined device requirement). The **Conditional Access** tab on the sign-in shows which policy applied. - If the client can't prove the device and the policy still isn't satisfied, expect the final row to be a device failure such as 53000 or 53001, or a block. - This is a strong control against stolen passwords and phished sessions, because the proof is tied to a device you manage. ## How do I fix AADSTS50097? **For the user:** sign in from a managed corporate device, using an app or browser your IT team supports for device sign-in. **For developers:** follow Microsoft's MSAL.NET page on device authentication errors (linked in sources) so the client can prove the device identity, or ask the admin whether the app should be in scope of a device-based policy. **For admins:** 1. Check whether the 50097 was followed by a success (first query). If yes, it was a normal step. 2. If not, and the IP or device is new for that user, treat the credential as exposed: reset the password, revoke sessions, review other sign-ins from that IP. 3. For an internal app that keeps failing, fix the client before you exclude it from the policy. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [MSAL.NET device authentication errors](https://learn.microsoft.com/en-us/entra/msal/dotnet/advanced/exceptions/device-authentication-errors) 3. [Troubleshoot sign-in problems with Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/troubleshoot-conditional-access) 4. [signIn resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/signin) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS53001](https://brambrinkmeier.com/entra/aadsts/53001/), [AADSTS135011](https://brambrinkmeier.com/entra/aadsts/135011/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS50155](https://brambrinkmeier.com/entra/aadsts/50155/), [AADSTS530002](https://brambrinkmeier.com/entra/aadsts/530002/), [AADSTS530003](https://brambrinkmeier.com/entra/aadsts/530003/), [AADSTS700003](https://brambrinkmeier.com/entra/aadsts/700003/), [AADSTS5000611](https://brambrinkmeier.com/entra/aadsts/5000611/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50097 fix: device authentication is required", https://brambrinkmeier.com/entra/aadsts/50097/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50105/ # AADSTS50105: User not assigned to a role for the app Canonical: https://brambrinkmeier.com/entra/aadsts/50105/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50105.json **Short answer:** AADSTS50105 means the user signed in successfully but isn't assigned to the application, and the app has "Assignment required" set to Yes. That is least privilege working. Fix it by assigning the user or a group, not by switching assignment off. Watch for repeated 50105 on sensitive apps. **Fix:** Admin: open Enterprise applications > the app > Users and groups and assign the user, or a group they are a direct member of. Don't set Assignment required to No as a quick fix. User: ask IT for access and give them the app name and the time you tried. | Field | Value | |---|---| | Code | AADSTS50105 | | Microsoft name | EntitlementGrantsNotFound | | Category | App configuration | | Type | Failure | | Attack signal | Low: usually configuration or user error | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-25 | ## What does AADSTS50105 mean? Microsoft's description: > **EntitlementGrantsNotFound**: The signed in user isn't assigned to a role for the signed in app. Assign the user to the app. Microsoft's troubleshooting article gives the cause: > The enterprise application's service principal has Assignment required? set to Yes, and the requesting user doesn't have an app role assignment ## Is it an attack? Almost always not. The usual causes are a new joiner who hasn't been added to the app's group yet, someone following a link to an app they don't use, or an assignment made through a **nested group**. The troubleshooting article advises: *"For predictable access, don't rely on nested group membership."* Assign the user directly, or use a group the user is a direct member of. The security point is what 50105 represents: **"Assignment required" is a least-privilege control, and 50105 is it refusing access.** That is the outcome you want. | Pattern | Likely meaning | |---|---| | One user, one app, a few attempts | Missing assignment or nested group. Benign. | | New starters failing on day one | Provisioning lag. Benign. | | One account trying many apps it isn't assigned to, in a short window | **Investigate.** A compromised account exploring what it can reach (reasoning, not a Microsoft statement). | | Rising 50105 on a sensitive app (admin portals, finance, HR) | Either a broken group, or people trying an app they aren't entitled to. Check which. | Microsoft's description says "the signed in user", so the credential stage succeeded before this check. Whoever produced the row either is that user or holds their credentials. ## How do I find it in my logs (KQL)? Accounts hitting many different apps they aren't assigned to: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50105" | summarize DeniedApps = dcount(AppId), AppNames = make_set(AppDisplayName, 10), IPs = make_set(IPAddress, 10), Attempts = count() by UserPrincipalName | where DeniedApps >= 3 | sort by DeniedApps desc ``` Daily 50105 per app, to see a broken assignment or a new pattern: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "50105" | summarize Users = dcount(UserPrincipalName), Attempts = count() by AppDisplayName, AppId, bin(TimeGenerated, 1d) | sort by TimeGenerated desc, Users desc ``` The threshold of 3 apps is a starting point, not a tested value. Tune it to your tenant. ## How does Conditional Access affect it? - 50105 is not a Conditional Access result. Assignment is a property of the enterprise application, checked separately from your CA policies. - A policy that targets "All resources" still applies to the user's other apps. Assignment decides **who** gets a token for this app; Conditional Access decides **under what conditions**. Use both. ## How do I fix AADSTS50105? **For the user:** ask your IT team for access to the app. Tell them the app name and the time you tried. **For admins:** 1. Open **Enterprise applications** > the app > **Users and groups**, and assign the user, or add them to a group that is assigned directly (not through a nested group). 2. Do **not** set **Assignment required?** to **No** as a quick fix. Microsoft's troubleshooting article warns: "Setting Assignment required? to No broadens token eligibility to include unassigned users and applications." 3. Remember Global Administrators are not a test of the setting. Microsoft notes: "The assignment requirement doesn't apply to Global Administrators." An app that works for an admin and fails for everyone else is behaving as configured. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Troubleshoot error AADSTS50105 (user not assigned to a role)](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50105-user-not-assigned-role) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS501051](https://brambrinkmeier.com/entra/aadsts/501051/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50105: User not assigned to a role for the app", https://brambrinkmeier.com/entra/aadsts/50105/ (CC BY 4.0), last updated 2026-10-25. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50125/ # AADSTS50125: Password reset registration interrupt Canonical: https://brambrinkmeier.com/entra/aadsts/50125/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50125.json **Short answer:** AADSTS50125 means sign-in was paused so the user could register for, or go through, self-service password reset. It is an expected interrupt and the password had already been accepted. If the sign-in came from an attacker IP, the attacker may be choosing the recovery details for the account. **Fix:** User: complete or confirm your password reset details. If the prompt appears on a device or at a time you don't recognise, contact IT. Admin: for a 50125 from an unfamiliar IP, remove recovery methods you can't tie to the user. Restrict registration to trusted locations or devices. | Field | Value | |---|---| | Code | AADSTS50125 | | Microsoft name | PasswordResetRegistrationRequiredInterrupt | | Category | Credentials and lockout | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS50125 mean? Microsoft's description: > **PasswordResetRegistrationRequiredInterrupt**: Sign-in was interrupted because of a password reset or password registration entry. Microsoft's description is all the official text there is. In practice this is the self-service password reset (SSPR) registration prompt (today part of combined security info registration): the user signed in successfully and is asked to set up or confirm the details used to reset their password later. That reading is from how the prompt behaves, not from a Microsoft statement. ## Is it an attack? For a real user it is routine. **It matters when the sign-in is not the user's.** The same logic as [50079](https://brambrinkmeier.com/entra/aadsts/50079/) applies. Whoever completes this step chooses the recovery details. An attacker with a working password who reaches 50125 can register their own phone or email as recovery info, and later use it to reset the password after the real user changes it. This is reasoning from what the prompt does, not a Microsoft statement. | Pattern | Likely meaning | |---|---| | 50125, then `0` from the user's usual IP and device | Normal SSPR registration or reconfirmation. Benign. | | 50125 from an IP that produced many **50126** failures | A spray found a working password, and the account is being asked for recovery info. | | 50125 from an unfamiliar IP, then a security info registration event, then `0` | **Likely account takeover** with attacker-controlled recovery details. | ## How do I find it in my logs (KQL)? 50125 from IPs the user has not had a successful sign-in from in the last 14 days: ```kusto let knownIPs = SigninLogs | where TimeGenerated > ago(14d) | where ResultType == "0" | distinct UserPrincipalName, IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50125" | join kind=leftanti knownIPs on UserPrincipalName, IPAddress | project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, ClientAppUsed, UserAgent | sort by TimeGenerated asc ``` 50125 followed within an hour by a security info registration in `AuditLogs` for the same user: ```kusto let interrupts = SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50125" | project InterruptTime = TimeGenerated, UserPrincipalName = tolower(UserPrincipalName), SigninIP = IPAddress; AuditLogs | where TimeGenerated > ago(7d) | where OperationName has "security info" | extend UserPrincipalName = tolower(tostring(InitiatedBy.user.userPrincipalName)), AuditIP = tostring(InitiatedBy.user.ipAddress) | join kind=inner interrupts on UserPrincipalName | where TimeGenerated between (InterruptTime .. (InterruptTime + 1h)) | project InterruptTime, RegisteredAt = TimeGenerated, UserPrincipalName, SigninIP, AuditIP, OperationName, Result | sort by RegisteredAt desc ``` Verify the exact `OperationName` values for security info and password reset registration in your own workspace before relying on the `has "security info"` filter, and check that `InitiatedBy` carries the user and IP fields for those events. `ResultType` is a **string** column, so compare it with `"50125"`. ## How do Conditional Access and MFA affect it? - 50125 comes from SSPR registration, not from a Conditional Access grant. It shows up after the password has been accepted. - Microsoft documents that an interrupted sign-in *"appears on the logs but shows **Not applied** for Conditional Access."* Look at the follow-up row for the policy result. - If your tenant lets users register security info from anywhere, this prompt is an opportunity for whoever holds the password. Restricting registration to trusted locations or devices with Conditional Access closes that path for this prompt and for [50079](https://brambrinkmeier.com/entra/aadsts/50079/). ## How do I fix AADSTS50125? **For the user:** complete or confirm your password reset details. If you get the prompt on a device or at a time you don't recognise, contact IT. **For admins:** 1. For a 50125 from an unfamiliar IP, review the user's registered recovery methods and remove any you can't tie to the user. 2. If an attacker registered details, reset the password, remove the methods, and revoke sessions (`Revoke-MgUserSignInSession`). 3. Restrict security info registration to trusted locations or devices. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-interactive-sign-ins) 3. [Revoke user access in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/users/users-revoke-access) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50079](https://brambrinkmeier.com/entra/aadsts/50079/), [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50055](https://brambrinkmeier.com/entra/aadsts/50055/), [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS50140](https://brambrinkmeier.com/entra/aadsts/50140/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50125: Password reset registration interrupt", https://brambrinkmeier.com/entra/aadsts/50125/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50126/ # AADSTS50126: Invalid username or password Canonical: https://brambrinkmeier.com/entra/aadsts/50126/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50126.json **Short answer:** AADSTS50126 means Microsoft Entra ID rejected the username or password. A few per day are normal typos. The security signal is the shape: many accounts failing from one IP is password spraying, many failures on one account is brute force. Hunt it in SigninLogs with ResultType == "50126". **Fix:** User: check the account name and keyboard layout, then reset your password with self-service reset if needed. Admin: if it's a spray, check whether any targeted account succeeded or reached MFA, then reset those passwords and revoke sessions. Block legacy authentication. | Field | Value | |---|---| | Code | AADSTS50126 | | Microsoft name | InvalidUserNameOrPassword | | Category | Credentials and lockout | | Type | Failure | | Attack signal | High: often seen in attacks | | MITRE ATT&CK | [T1110.003](https://attack.mitre.org/techniques/T1110/003/) Brute Force: Password Spraying, [T1110.001](https://attack.mitre.org/techniques/T1110/001/) Brute Force: Password Guessing | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-25) | | Last updated | 2026-10-30 | ## What does AADSTS50126 mean? Microsoft's description: > **InvalidUserNameOrPassword**: Error validating credentials due to invalid username or password. The user didn't enter the right credentials. Expect to see some number of these errors in your logs due to users making mistakes. Source: [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes). The request reached the password check and failed. Nothing after that ran: no MFA prompt and no Conditional Access evaluation. ## Reproduced in the lab On 25 October 2026 an automated lab run sent a token request for an existing test user with the wrong password. Entra returned `AADSTS50126` with this first line: > AADSTS50126: Error validating credentials due to invalid username or password. That confirms the code and its wording at the token endpoint. The same attempt in the lab tenant's sign-in log (Entra admin center, interactive user sign-ins), with identifiers left out: | Field | Value in the lab row | |---|---| | Status | Failure | | Sign-in error code | 50126 | | Failure reason | Error validating credentials due to invalid username or password. | | Additional details | The user didn't enter the right credentials. It's expected to see some number of these errors in your logs due to users making mistakes. | | Authentication details | Password (password in the cloud), succeeded: false | | Authentication requirement | Single-factor authentication | | Conditional Access | Not Applied | | Resource | Microsoft Graph | | User type | Member | In the real row Conditional Access shows **Not Applied**: a wrong password stops the sign-in before any policy is evaluated, which is why a spray that never guesses right leaves no Conditional Access trace. The KQL below was run on the lab rows ([how](https://brambrinkmeier.com/methodology/)). Both queries returned nothing as written, as expected: the lab sends one wrong password per run, far below the spray threshold of 10 users. With the threshold lowered to 1, the spray query found both source IPs and the follow-up query found the next sign-ins from those IPs. ## Is it an attack? [Microsoft itself says](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) a baseline of 50126 is expected. **The signal is the distribution, not the presence.** The [password spray guide](https://brambrinkmeier.com/guides/detect-password-spray-entra-id/) turns the patterns below into a step-by-step investigation. | Pattern | Likely meaning | |---|---| | 1–3 failures, then a success from the same IP and device | A user typo. Benign. | | Many **different users**, few attempts each, from one IP or a small IP range | **Password spraying** (T1110.003) | | Many attempts against **one user** | Brute force / password guessing (T1110.001) | | Failures via `ClientAppUsed` = IMAP, POP, SMTP, Exchange ActiveSync, other legacy clients | Spray tooling using legacy protocols, which can't do MFA | | 50126 followed by **50053** for the same accounts | The spray tripped smart lockout | | 50126 followed by **50076/50074** or **53003** from the same IP | **The password was correct** on a later try. MFA or Conditional Access is now the only barrier. Treat it as a compromised password. | Two details from Microsoft's documentation matter when you read these rows: - **Conditional Access never ran.** CA [only evaluates after the first factor succeeds](https://learn.microsoft.com/en-us/entra/identity/conditional-access/overview), so 50126 rows show `ConditionalAccessStatus` = `notApplied`. That doesn't mean your policies are missing. - **`AuthenticationRequirement` shows `singleFactorAuthentication` even in an MFA-enforced tenant**, because MFA was never reached ([sign-in log activity details](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-in-log-activity-details)). Don't use it as evidence that MFA is off. ## How do I find it in my logs (KQL)? Spray pattern: one IP, many distinct users failing, over the last day. ```kusto SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50126" | summarize FailedUsers = dcount(UserPrincipalName), Attempts = count(), Apps = make_set(AppDisplayName, 5), Clients = make_set(ClientAppUsed, 5) by IPAddress | where FailedUsers >= 10 | sort by FailedUsers desc ``` Did any of those IPs **also get a correct password**? That is the row that matters: ```kusto let sprayIPs = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50126" | summarize FailedUsers = dcount(UserPrincipalName) by IPAddress | where FailedUsers >= 10 | project IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where IPAddress in (sprayIPs) | where ResultType in ("0", "50076", "50074", "50079", "53003", "50055") | project TimeGenerated, UserPrincipalName, IPAddress, ResultType, ResultDescription, ConditionalAccessStatus, AppDisplayName, ClientAppUsed | sort by TimeGenerated asc ``` `ResultType` is a **string** column, so compare it with `"50126"`, not `50126`. Legacy-protocol sign-ins that replay a stored password can also show up in `AADNonInteractiveUserSignInLogs`; run the same query there if you allow legacy auth. ## How do Conditional Access and MFA affect it? - CA can't stop a 50126. It happens before CA runs. What CA controls is what happens **after** a correct password (MFA, compliant device, block). - **Blocking legacy authentication** removes the protocols most spray tools use, and those protocols can't do MFA. - **[Smart lockout](https://learn.microsoft.com/en-us/entra/identity/authentication/howto-password-smart-lockout)** is always on. By default it locks after 10 failed attempts (Azure public cloud), with separate counters for familiar and unfamiliar locations, which then turns the errors into 50053. ## How do I fix AADSTS50126? **For the user:** check the account name and keyboard layout, then reset the password with self-service password reset if needed. **For admins:** 1. If it's a spray, check whether any targeted account **succeeded** or reached MFA (second query above). Reset those passwords and revoke sessions. 2. Block legacy authentication with Conditional Access. 3. Make sure every account has a registered phishing-resistant MFA method, so a correct password alone isn't enough. 4. Consider custom banned passwords. Spray lists use seasonal and company-name passwords. 5. If the failures come from the IP address of one of your own servers, check that server for compromise. A host that was breached may be trying credentials it found on it. See [hunting credential reuse after a web-server breach](https://brambrinkmeier.com/guides/hunt-credential-reuse-after-web-server-breach/). ## Evidence Reproduced in a lab tenant on 2026-10-25 (ROPC token request against a lab tenant; scenario: Wrong password). First line returned: > AADSTS50126: Error validating credentials due to invalid username or password. Sign-in log row read: 2026-10-30. KQL run against the exported lab rows: 2026-10-30. Lab-run rows naming this code (11; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Wrong password | 50126 | 50126 | AADSTS50126: Error validating credentials due to invalid username or password. | | 2026-10-30 | Wrong password | 50126 | 50126 | AADSTS50126: Error validating credentials due to invalid username or password. | | 2026-10-30 | Old password after an admin reset | 50054 / 50126 | error | Graph PATCH /users/{object-id}: HTTP 403 {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete | | 2026-10-30 | Wrong password | 50126 | 50126 | AADSTS50126: Error validating credentials due to invalid username or password. | | 2026-10-30 | Repeated wrong passwords (smart lockout) | 50053 | 50126 | AADSTS50126: Error validating credentials due to invalid username or password. | | 2026-10-30 | Wrong password | 50126 | 50126 | AADSTS50126: Error validating credentials due to invalid username or password. | | 2026-10-30 | Wrong password | 50126 | 50126 | AADSTS50126: Error validating credentials due to invalid username or password. | | 2026-10-30 | Wrong password | 50126 | 50126 | AADSTS50126: Error validating credentials due to invalid username or password. | | 2026-10-30 | Wrong password | 50126 | 50126 | AADSTS50126: Error validating credentials due to invalid username or password. | | 2026-10-31 | Wrong password | 50126 | 50126 | AADSTS50126: Error validating credentials due to invalid username or password. | | 2026-10-31 | Wrong password | 50126 | 50126 | AADSTS50126: Error validating credentials due to invalid username or password. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 3. [Protect user accounts from attacks with Microsoft Entra smart lockout](https://learn.microsoft.com/en-us/entra/identity/authentication/howto-password-smart-lockout) 4. [Sign-in log activity details](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-in-log-activity-details) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 6. [What is Conditional Access? (Microsoft Entra)](https://learn.microsoft.com/en-us/entra/identity/conditional-access/overview) ## Related codes [AADSTS50053](https://brambrinkmeier.com/entra/aadsts/50053/), [AADSTS50057](https://brambrinkmeier.com/entra/aadsts/50057/), [AADSTS50055](https://brambrinkmeier.com/entra/aadsts/50055/), [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS50052](https://brambrinkmeier.com/entra/aadsts/50052/), [AADSTS50054](https://brambrinkmeier.com/entra/aadsts/50054/), [AADSTS50074](https://brambrinkmeier.com/entra/aadsts/50074/), [AADSTS50079](https://brambrinkmeier.com/entra/aadsts/50079/), [AADSTS50125](https://brambrinkmeier.com/entra/aadsts/50125/), [AADSTS50133](https://brambrinkmeier.com/entra/aadsts/50133/), [AADSTS50140](https://brambrinkmeier.com/entra/aadsts/50140/), [AADSTS50158](https://brambrinkmeier.com/entra/aadsts/50158/), [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS70002](https://brambrinkmeier.com/entra/aadsts/70002/), [AADSTS500121](https://brambrinkmeier.com/entra/aadsts/500121/), [AADSTS530032](https://brambrinkmeier.com/entra/aadsts/530032/), [AADSTS900144](https://brambrinkmeier.com/entra/aadsts/900144/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50126: Invalid username or password", https://brambrinkmeier.com/entra/aadsts/50126/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50133/ # AADSTS50133: Session invalid after password change or expiry Canonical: https://brambrinkmeier.com/entra/aadsts/50133/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50133.json **Short answer:** AADSTS50133 means Microsoft Entra ID rejected an existing sign-in session because the user's password expired or was recently changed. It is normally a one-off after a password change. After a compromise, rows from IPs or devices the user doesn't own show where an old session was still in use. Hunt it in SigninLogs and AADNonInteractiveUserSignInLogs. **Fix:** User: sign in again with your new password. Admin: if this follows a suspected compromise, also revoke sessions (`Revoke-MgUserSignInSession`), then list where old sessions were presented after the reset and block any IP that isn't the user's. | Field | Value | |---|---| | Code | AADSTS50133 | | Microsoft name | SsoArtifactRevoked | | Category | Tokens and sessions | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS50133 mean? Microsoft's description: > **SsoArtifactRevoked**: The session isn't valid due to password expiration or recent password change. A client presented a session that existed before the password changed or expired. Microsoft no longer accepts it. The user has to sign in again. Two close relatives in the reference table: - **50132 SsoArtifactInvalidOrExpired** carries the same description text: *"The session isn't valid due to password expiration or recent password change."* - **50089**: *"Authentication failed due to flow token expired. Expected - auth codes, refresh tokens, and sessions expire over time or are revoked by the user or an admin."* ## Is it an attack? See the [comparison of the codes behind "asked to sign in again"](https://brambrinkmeier.com/guides/why-user-asked-to-sign-in-again-entra-id/) (70043, 700082, 50173, 50133, 50076). Almost never on its own. 50133 is the normal consequence of a password change or expiry. It is the session counterpart of [50173](https://brambrinkmeier.com/entra/aadsts/50173/), which is the same idea for refresh tokens. The [session revocation guide](https://brambrinkmeier.com/guides/revoke-sessions-and-verify-entra-id/) shows how both codes prove a response worked. | Pattern | Likely meaning | |---|---| | A few 50133 rows for one user right after their password change, from their usual IPs and devices, then a success | The user's own sessions being reset. Benign. | | 50133 after you reset a **compromised** user's password, from an IP or device you can't tie to the user | A session you didn't know about was still being used. Treat it as an attacker indicator and pivot on the IP. | | 50133 for many users at once | A batch of password expiries or a bulk reset. Check your password policy and change history before investigating further. | This is reasoning from Microsoft's description, not a documented detection: the code tells you a pre-change session was presented, and the row tells you from where. Whether that location is suspicious is your call. ## How do I find it in my logs (KQL)? After a password reset on a user you suspect was compromised, list every place an old session was presented. `DeviceDetail` and `LocationDetails` are dynamic in `SigninLogs` and **strings** in `AADNonInteractiveUserSignInLogs`, so each side is normalised before the union. ```kusto let targetUser = "{user-principal-name}"; let resetAt = datetime(2026-10-11T09:00:00Z); union (SigninLogs | extend Device = DeviceDetail, Location = LocationDetails, Table = "Interactive"), (AADNonInteractiveUserSignInLogs | extend Device = parse_json(DeviceDetail), Location = parse_json(LocationDetails), Table = "NonInteractive") | where TimeGenerated > resetAt | where UserPrincipalName =~ targetUser | where ResultType in ("50133", "50132") | summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Apps = make_set(AppDisplayName, 10) by Table, ResultType, IPAddress, Country = tostring(Location.countryOrRegion), OS = tostring(Device.operatingSystem), Browser = tostring(Device.browser), DeviceId = tostring(Device.deviceId), UserAgent | sort by FirstSeen asc ``` Tenant-wide baseline, so you know what normal looks like before an incident: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "50133" | summarize Rows = count(), Users = dcount(UserPrincipalName) by bin(TimeGenerated, 1d) | sort by TimeGenerated asc ``` `ResultType` is a **string** column, so compare it with `"50133"`, not `50133`. The JSON field names inside `Device` and `Location` follow the Microsoft Graph `signIn` resource; check them against a row in your own workspace. ## How do Conditional Access and MFA affect it? - No Conditional Access policy causes 50133. The password change does. - The fresh sign-in that follows goes through the password check, MFA and Conditional Access again. An old session no longer skips those checks. - If the attacker may have registered their own MFA method on the account, a password reset alone is not the whole response. Review the user's registered methods as part of the same incident. ## How do I fix AADSTS50133? **For the user:** sign in again with the new password. **For admins:** 1. If this follows a suspected compromise, also revoke sessions explicitly (`Revoke-MgUserSignInSession -UserId $User.Id` or **Revoke sessions**). That is Microsoft's documented response step. Refresh tokens that fail after a revocation or password change show up as [50173](https://brambrinkmeier.com/entra/aadsts/50173/). 2. Run the first query for the time after the reset and block any IP that isn't the user's. 3. If you see 50133 for many users unexpectedly, check for a password expiry wave before treating it as an incident. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Revoke user access in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/users/users-revoke-access) 3. [Sign-in log activity details](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-in-log-activity-details) 4. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadnoninteractiveusersigninlogs) ## Related codes [AADSTS50173](https://brambrinkmeier.com/entra/aadsts/50173/), [AADSTS50055](https://brambrinkmeier.com/entra/aadsts/50055/), [AADSTS70043](https://brambrinkmeier.com/entra/aadsts/70043/), [AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50054](https://brambrinkmeier.com/entra/aadsts/50054/), [AADSTS50089](https://brambrinkmeier.com/entra/aadsts/50089/), [AADSTS50140](https://brambrinkmeier.com/entra/aadsts/50140/), [AADSTS70008](https://brambrinkmeier.com/entra/aadsts/70008/), [AADSTS70044](https://brambrinkmeier.com/entra/aadsts/70044/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50133: Session invalid after password change or expiry", https://brambrinkmeier.com/entra/aadsts/50133/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50140/ # AADSTS50140: Keep me signed in interrupt Canonical: https://brambrinkmeier.com/entra/aadsts/50140/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50140.json **Short answer:** AADSTS50140 is the "Keep me signed in?" prompt, logged as an interrupt. Microsoft calls it an expected part of the sign-in flow, so it is noise on failure dashboards. Its one investigative use: the prompt comes after authentication, so a 50140 from an attacker IP almost certainly means the password and any required MFA were accepted. **Fix:** Nothing to fix: this is the 'Keep me signed in?' prompt. User: choose Yes or No. Admin: exclude 50140 from failure alerts, but count it as a success in incident timelines. If it came from an attacker IP, reset the password and revoke sessions. | Field | Value | |---|---| | Code | AADSTS50140 | | Microsoft name | KmsiInterrupt | | Category | Tokens and sessions | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Low: usually configuration or user error | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS50140 mean? Microsoft's description: > **KmsiInterrupt**: This error occurred due to "Keep me signed in" interrupt when the user was signing-in. This is an expected part of the sign in flow, where a user is asked if they want to remain signed into their current browser to make further logins easier. The user saw the "Stay signed in?" question. Answering it, either way, completes the sign-in on the next request. ## Is it an attack? No, not by itself. It is one of the most common reasons sign-in reports show "failures" that aren't failures. **It still matters in an investigation because of where it sits in the flow.** The prompt asks whether to *remain* signed in, so it appears once authentication has been accepted. That is reasoning from Microsoft's description, not a separate Microsoft statement, but it means a 50140 is close to a success row for timeline purposes. | Pattern | Likely meaning | |---|---| | 50140, then `0` seconds later, same IP and device | Normal browser sign-in. Benign. | | 50140 counted as a failure on a dashboard or alert | Noise. Exclude it. | | 50140 from an IP tied to a spray, a phishing kit, or an unfamiliar country | **The attacker got through password and MFA.** Treat it like a successful sign-in. | Microsoft's password spray playbook ranks *"Interrupted sign-in by known attacker IP address"* right after successful ones when prioritising. A 50140 is an interrupt that comes after authentication, so it belongs at the top of that list. ## How do I find it in my logs (KQL)? Every sign-in from a list of suspect IPs that got past authentication, counting 50140 as a success: ```kusto let suspectIPs = dynamic(["{ip-address}", "{ip-address}"]); SigninLogs | where TimeGenerated > ago(7d) | where IPAddress in (suspectIPs) | where ResultType in ("0", "50140") | project TimeGenerated, UserPrincipalName, IPAddress, ResultType, AppDisplayName, ClientAppUsed, AuthenticationRequirement, UserAgent | sort by TimeGenerated asc ``` Replace the example IPs with your own. A failure overview that leaves out expected interrupts: ```kusto SigninLogs | where TimeGenerated > ago(1d) | where ResultType != "0" | where ResultType !in ("50140", "50076", "50158", "50125", "50079") | summarize Events = count(), Users = dcount(UserPrincipalName) by ResultType, ResultDescription | sort by Events desc ``` Excluding 50076 and 50079 hides them from a failure count. It doesn't make them irrelevant. Hunt those codes separately. ## How do Conditional Access and MFA affect it? - 50140 is not a Conditional Access or MFA outcome. It is a prompt about keeping the browser signed in. - Any MFA or Conditional Access requirement for the sign-in was handled before this prompt. To see which policies applied, look at the related success row for the same user, IP and time, not at the 50140 row. - An attacker who answers "Yes" is asking for a longer-lived browser session. After a compromise, end it explicitly by revoking sessions. ## How do I fix AADSTS50140? **For the user:** nothing to fix. Choose Yes or No. **For admins:** 1. Exclude 50140 from failure alerts and dashboards. 2. Include it as a success-equivalent in incident timelines for suspicious IPs. 3. If a 50140 came from an attacker IP, reset the password and revoke sessions (`Revoke-MgUserSignInSession`, or **Revoke sessions** on the user in the admin center). ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 3. [Revoke user access in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/users/users-revoke-access) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS50074](https://brambrinkmeier.com/entra/aadsts/50074/), [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/), [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50173](https://brambrinkmeier.com/entra/aadsts/50173/), [AADSTS50133](https://brambrinkmeier.com/entra/aadsts/50133/), [AADSTS50125](https://brambrinkmeier.com/entra/aadsts/50125/), [AADSTS50158](https://brambrinkmeier.com/entra/aadsts/50158/), [AADSTS165000](https://brambrinkmeier.com/entra/aadsts/165000/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50140: Keep me signed in interrupt", https://brambrinkmeier.com/entra/aadsts/50140/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50146/ # AADSTS50146 fix: custom claims need an app signing key Canonical: https://brambrinkmeier.com/entra/aadsts/50146/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50146.json **Short answer:** AADSTS50146 means Microsoft Entra ID refused to issue a token because the app's claims were customized but the app hasn't accepted that: it has no app-specific signing key (or the key expired), and it doesn't set acceptMappedClaims. It usually starts right after someone adds a claim to an app. It is a configuration error and a deliberate safeguard. Low attack value. **Fix:** Developer, single-tenant app: set `acceptMappedClaims` to `true` in the app manifest and use a verified-domain Application ID URI. Multitenant app: add a custom signing key to the service principal and validate tokens with `?appid=`. Expired key: renew it. User: contact the app owner. | Field | Value | |---|---| | Code | AADSTS50146 | | Microsoft name | MissingCustomSigningKey | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS50146 mean? Microsoft's description: > **MissingCustomSigningKey**: This app is required to be configured with an app-specific signing key. It's either not configured with one, or the key has expired or isn't yet valid. Please contact the owner of the application. The trigger is **claims customization**: someone changed which claims Entra ID puts in the app's tokens. Microsoft explains why that needs an extra step: *"Applications that receive tokens rely on claim values that can't be tampered with. When you modify the token contents through claims customization, these assumptions may no longer be correct. Applications must explicitly acknowledge that tokens have been modified."* The app can acknowledge it in one of two ways: - **A custom signing key** on the service principal. By default an app *"is using the Azure global sign-in key, which can't be used for customizing claims in tokens."* - **`acceptMappedClaims` set to `true`** in the app manifest. This is for single-tenant apps only. *"Without this, Microsoft Entra ID returns an AADSTS50146 error code."* The description also covers a custom key that exists but has expired or isn't valid yet. ## Is it an attack? No. 50146 is the safeguard working. Microsoft's warning on the alternative shows what it protects against: *"Do not set the acceptMappedClaims property to true for multi-tenant apps, which can allow malicious actors to create claims-mapping policies for your app."* Users report it after ordinary changes: - In a Microsoft Q&A thread, a developer added the optional claim `onpremisessamaccountname` to a single-tenant app with a SPA and an API scope, and sign-in started failing with 50146. - Auth0's knowledge base covers it on an Auth0 connection to Entra ID, where the token request fails with *"failed to obtain access token"*. | Pattern | Likely meaning | |---|---| | One app, every user, starting right after a claim was added | Claims customization without a signing key or `acceptMappedClaims`. Configuration. | | An app that worked for months starts failing for everyone | The custom signing key has expired. | | A claims-mapping policy appears on an app nobody on your team changed | Not 50146 itself, but worth a look. Our interpretation: someone is changing what tokens for that app contain. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 50146 lands in. Check your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "50146" | summarize Rows = count(), Apps = dcount(AppId), FirstSeen = min(TimeGenerated) by SourceTable ``` Which apps fail and since when: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "50146" | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Resources = make_set(ResourceDisplayName, 5) by AppDisplayName, AppId | sort by Users desc ``` Recent policy and app changes, to find the change that started it. Microsoft lists **Add policy to service principal**, **Add policy to application** and **Update application** as audit activities. Our assumption: assigning a claims-mapping policy appears as one of the first two, and a manifest change as the third; Microsoft doesn't map them explicitly. ```kusto AuditLogs | where TimeGenerated > ago(30d) | where Category == "ApplicationManagement" | where OperationName in ("Add policy to service principal", "Add policy to application", "Update application") | extend Target = tostring(TargetResources[0].displayName), ByUser = tostring(InitiatedBy.user.userPrincipalName) | project TimeGenerated, OperationName, Target, ByUser, Result | sort by TimeGenerated desc ``` `ResultType` is a **string** column, so compare it with `"50146"`. ## How do I fix AADSTS50146? **For the user:** you can't fix this. As Microsoft's description says, contact the owner of the application. **For developers, single-tenant app:** 1. In the app manifest, set `acceptMappedClaims` to `true`. Microsoft: *"Setting the property allows an application to use claims mapping without specifying a custom signing key."* 2. Set the **Application ID URI** to a verified domain of your tenant, for example `https://contoso.com/my-api`. If you don't, you trade 50146 for AADSTS501461: *"AcceptMappedClaims is only supported for a token audience matching the application GUID or an audience within the tenant's verified domains."* The Q&A thread above hit exactly this with an `api://` URI. **For developers, multitenant app:** 1. Don't use `acceptMappedClaims`. Microsoft: *"For multitenant apps, a custom signing key should be used."* 2. Create a key from a certificate and add it to the **service principal**: the private key and public key as key credentials, and the password as a password credential, with matching `keyId` values. The private key must be in PKCS#12 format. 3. Validate tokens against the app's own keys. Apps with claims mapping *"must validate their token signing keys by appending `appid={client_id}` to their OpenID Connect metadata requests"*: `https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration?appid={client-id}`. **For admins:** 1. Check the app's recent changes (third query). If a claim was added, the developer needs one of the two fixes above. 2. If the app already has a custom signing key, check whether it has expired. The description names an expired or not-yet-valid key as a cause. Replace it with a new certificate. 3. Some settings only work with a custom key. Microsoft says the **Issuer With Application ID** and **Audience Override** settings are *"ignored if a custom signing key isn't configured for the application."* ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Customize claims issued in the JSON web token (JWT) for enterprise applications](https://learn.microsoft.com/en-us/entra/identity-platform/jwt-claims-customization) 3. [Claims customization using a policy](https://learn.microsoft.com/entra/identity-platform/reference-claims-customization) 4. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) 5. [After adding a new claim to an app I am getting AADSTS50146 (Microsoft Q&A, user report)](https://learn.microsoft.com/en-us/answers/questions/2180433/after-adding-a-new-claims-to-an-app-i-am-getting-t) 6. [Failed to obtain access token and error AADSTS50146 (Auth0 KB, user report)](https://support.auth0.com/center/s/article/microsoft-azure-ad-entra-id-failed-to-obtain-access-token-and-error-aadsts50146) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50146 fix: custom claims need an app signing key", https://brambrinkmeier.com/entra/aadsts/50146/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50155/ # AADSTS50155: Device authentication failed (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/50155/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50155.json **Short answer:** AADSTS50155 means Microsoft Entra ID couldn't authenticate the user's device, so it can't issue a Primary Refresh Token. Microsoft's main cause is a device that was deleted or disabled in Entra ID. The fix is to re-enable or re-register the device. Attack value is low, but 50155 from a device you disabled because it was lost is worth a look. **Fix:** Admin: find the device in the Entra admin center. Re-enable it if it was disabled, or re-register it for its join type (for example `dsregcmd /forcerecovery` on an Entra joined device). Don't re-enable a lost or stolen device. User: tell IT what the device message says. | Field | Value | |---|---| | Code | AADSTS50155 | | Microsoft name | DeviceAuthenticationFailed | | Category | Devices | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS50155 mean? Microsoft's description: > **DeviceAuthenticationFailed**: Device authentication failed for this user. The device tried to prove its identity to Microsoft Entra ID and failed. Microsoft's Primary Refresh Token (PRT) troubleshooting guide gives the cause: *"Microsoft Entra ID can't authenticate the device to issue a PRT"*, and *"The device might have been deleted or disabled."* Without a PRT, single sign-on on the Windows device stops working. The device FAQ describes what users see: a message that *"Your organization has deleted the device"* or *"Your organization has disabled the device"*. It explains why: *"The validity of the PRT is based on the validity of the device itself."* ## Is it an attack? Usually not. Microsoft's device FAQ lists how a device ends up deleted or disabled, and none of them is an attack on the sign-in: | Pattern | Likely meaning | |---|---| | 50155 for one user right after an admin cleaned up stale devices | The device object was deleted or disabled. Benign. Re-register or re-enable it. | | 50155 for a hybrid joined device after an OU change in Entra Connect | Microsoft: *"An administrator removes the devices OU out of sync scope resulting in the devices being deleted from Microsoft Entra ID."* | | 50155 for a hybrid joined device whose computer account was disabled on-premises | Microsoft: disabling the computer account on-premises results *"in the device being disabled in Microsoft Entra ID."* | | 50155 after a user disabled their own device | Microsoft lists *"User disables the device from the My Apps portal."* | | 50155 from a device you disabled because it was lost or stolen | Microsoft says admins do this *"for stale, lost, or stolen devices to prevent unauthorized access."* The control is working. Our reading: someone is still using that device, so check who and from where. | The last row is the only one worth a security look. Even then, the failure means the device got no PRT. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 50155 is logged in. Check where it lands. `DeviceDetail` is `dynamic` in `SigninLogs` but `string` in `AADNonInteractiveUserSignInLogs`, so the query normalises it before the union: ```kusto union withsource=SourceTable (SigninLogs | extend Dev = todynamic(DeviceDetail)), (AADNonInteractiveUserSignInLogs | extend Dev = todynamic(DeviceDetail)) | where TimeGenerated > ago(7d) | where ResultType == "50155" | summarize Rows = count(), Users = dcount(UserPrincipalName), Devices = dcount(tostring(Dev.deviceId)) by SourceTable ``` Which devices and users fail. `deviceId`, `displayName`, `operatingSystem` and `trustType` are properties of the Graph `deviceDetail` type; Microsoft notes the device ID and name are *"Populated for devices registered in Microsoft Entra"*: ```kusto union (SigninLogs | extend Dev = todynamic(DeviceDetail)), (AADNonInteractiveUserSignInLogs | extend Dev = todynamic(DeviceDetail)) | where TimeGenerated > ago(7d) | where ResultType == "50155" | extend DeviceId = tostring(Dev.deviceId), DeviceName = tostring(Dev.displayName), OS = tostring(Dev.operatingSystem), TrustType = tostring(Dev.trustType) | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), IPs = make_set(IPAddress, 5), Apps = make_set(AppDisplayName, 5) by UserPrincipalName, DeviceName, DeviceId, OS, TrustType | sort by Rows desc ``` Devices that were deleted or disabled in the directory recently, to match against the list above. `Delete device` and `Update device` are activities in the `Device` category of the audit log. Matching on the device name is our approach: the audit log identifies the device by its object, and we haven't checked that this ID equals the `deviceId` in sign-in logs: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where Category == "Device" | where OperationName in ("Delete device", "Update device") | extend DeviceName = tostring(TargetResources[0].displayName), Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)) | project TimeGenerated, OperationName, DeviceName, Actor, Result | sort by TimeGenerated desc ``` `Update device` covers more than disabling, so open the row's `TargetResources` to see what changed. `ResultType` in the sign-in tables is a **string** column, so compare it with `"50155"`, not `50155`. ## How do I fix AADSTS50155? **For the user:** tell your IT team the device shows *"Your organization has deleted the device"* or *"has disabled the device"*. You can't fix it alone if the device was disabled; an admin has to re-enable it. **For admins:** 1. Find the device in the Microsoft Entra admin center. Microsoft's solution is to *"Re-register the device based on the device join type."* 2. **Disabled device:** an admin can enable it again in the Microsoft Entra admin center. For hybrid joined devices synced with Entra Connect, Microsoft notes they are *"automatically re-enabled during the next sync cycle"*, so disable those in on-premises AD instead. 3. **Deleted, Microsoft Entra hybrid joined:** in an elevated command prompt run `dsregcmd.exe /debug /leave`, then sign out and sign in to trigger the scheduled task that registers the device again. 4. **Deleted, Microsoft Entra joined:** in an elevated command prompt run `dsregcmd /forcerecovery`, select **Sign in** in the dialog, finish the sign-in, then sign out and back in. 5. **Deleted, Microsoft Entra registered:** go to **Settings** > **Accounts** > **Access Work or School**, select the account, select **Disconnect**, then **Connect** and register again. 6. Check `dsregcmd /status` afterwards. The PRT guide uses it to check the PRT state. 7. If the device was disabled because it was lost or stolen, don't re-enable it. Use the second query to see which IPs it still signs in from. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Troubleshoot primary refresh token issues on Windows devices](https://learn.microsoft.com/en-us/entra/identity/devices/troubleshoot-primary-refresh-token) 3. [Microsoft Entra device management FAQ](https://learn.microsoft.com/en-us/entra/identity/devices/faq) 4. [Microsoft Entra audit log activity reference](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) 5. [deviceDetail resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/devicedetail?view=graph-rest-1.0) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 7. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadnoninteractiveusersigninlogs) ## Related codes [AADSTS50097](https://brambrinkmeier.com/entra/aadsts/50097/), [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS53001](https://brambrinkmeier.com/entra/aadsts/53001/), [AADSTS135011](https://brambrinkmeier.com/entra/aadsts/135011/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50155: Device authentication failed (fix)", https://brambrinkmeier.com/entra/aadsts/50155/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50158/ # AADSTS50158: External security challenge not satisfied Canonical: https://brambrinkmeier.com/entra/aadsts/50158/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50158.json **Short answer:** AADSTS50158 means the user was redirected to satisfy an extra requirement, such as terms of use or a third-party MFA provider, before sign-in could finish. Microsoft says the code alone does not indicate a failure. Read it like an MFA interrupt: from an attacker IP, it means the password worked and the external challenge is the remaining barrier. **Fix:** User: finish the step you were sent to, such as accepting the terms of use or completing the external MFA prompt. If it keeps failing, contact IT with the time. Admin: don't alert on 50158 alone. From a spray IP, reset the password and check the external MFA provider's logs. | Field | Value | |---|---| | Code | AADSTS50158 | | Microsoft name | External security challenge not satisfied | | Category | Multifactor authentication | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Low: usually configuration or user error | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS50158 mean? Microsoft's description: > **External security challenge not satisfied**: User will be redirected to another page or authentication provider to satisfy additional authentication challenges. The user is required to satisfy additional requirements before finishing authentication, and was redirected to another page (such as terms of use or a third party MFA provider). This code alone doesn't indicate a failure on your users' part to sign in. The sign in logs may indicate that this challenge was successfully passed or failed. The reference table gives this code no PascalCase name, so the description is used as its name here. ## Is it an attack? Microsoft says directly that the code alone is not a failure. **What happened next is in the following sign-in rows.** Read it the same way as [50076](https://brambrinkmeier.com/entra/aadsts/50076/): the first factor was accepted and an extra step is pending. | Pattern | Likely meaning | |---|---| | 50158, then `0` from the same IP and device | The user accepted the terms of use or passed the external MFA. Benign. | | 50158 with no later success, for a user who is not complaining | The user abandoned the sign-in, or the external provider rejected the challenge. Check the provider's own logs. | | 50158 from an IP that also produced many **50126** failures | **A spray found a correct password.** The external MFA or terms-of-use step is the only thing left. | | Repeated 50158 for one user from an unfamiliar IP | Someone with the password retrying against the external MFA. Same reading as repeated [50074](https://brambrinkmeier.com/entra/aadsts/50074/). | If you use an external MFA integration, the Entra sign-in log only shows the redirect. Whether the user approved, denied or ignored the challenge is recorded by that provider. `TokenIssuerType` can tell you whether federation services or an MFA adapter were involved (documented values include `ADFederationServicesMFAAdapter` and `NPSExtension`). ## How do I find it in my logs (KQL)? 50158 rows with whether the same user and IP had a success in the next 30 minutes: ```kusto let challenges = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50158" | project ChallengeTime = TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, TokenIssuerType; let successes = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "0" | project SuccessTime = TimeGenerated, UserPrincipalName, IPAddress; challenges | join kind=leftouter successes on UserPrincipalName, IPAddress | extend Followed = isnotnull(SuccessTime) and SuccessTime between (ChallengeTime .. (ChallengeTime + 30m)) | summarize Successes = countif(Followed) by ChallengeTime, UserPrincipalName, IPAddress, AppDisplayName, TokenIssuerType | extend Completed = Successes > 0 | sort by ChallengeTime desc ``` 50158 from IPs that were failing passwords against several users the same day: ```kusto let sprayIPs = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50126" | summarize FailedUsers = dcount(UserPrincipalName) by IPAddress | where FailedUsers >= 5 | project IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50158" | where IPAddress in (sprayIPs) | project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, ClientAppUsed, TokenIssuerType, UserAgent | sort by TimeGenerated asc ``` The 30-minute window and the threshold of 5 are starting points, not Microsoft numbers. `ResultType` is a **string** column, so compare it with `"50158"`. ## How do Conditional Access and MFA affect it? - 50158 shows up when a Conditional Access terms of use control or an external or third-party MFA provider has to run before the sign-in finishes. - Microsoft documents that an interrupted sign-in *"appears on the logs but shows **Not applied** for Conditional Access."* Look at the follow-up row for the policy result. - When MFA is handled outside Entra ID, Entra's sign-in logs can't show whether a push was denied or approved. MFA fatigue against an external provider has to be hunted in that provider's logs. ## How do I fix AADSTS50158? **For the user:** finish the step you were sent to: accept the terms of use or complete the external MFA prompt. If it keeps failing, contact IT with the time of the sign-in. **For admins:** 1. Don't alert on 50158 alone. Alert on 50158 from IPs you already consider hostile. 2. For a 50158 from a spray IP, treat the password as compromised and reset it, even if the external MFA held. 3. Check the external MFA provider's logs for the same user and time to see whether the challenge was denied, ignored or approved. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 3. [Interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-interactive-sign-ins) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS50074](https://brambrinkmeier.com/entra/aadsts/50074/), [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS50140](https://brambrinkmeier.com/entra/aadsts/50140/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50158: External security challenge not satisfied", https://brambrinkmeier.com/entra/aadsts/50158/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50173/ # AADSTS50173: Grant expired because it was revoked Canonical: https://brambrinkmeier.com/entra/aadsts/50173/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50173.json **Short answer:** AADSTS50173 means a refresh token was rejected because it was issued before the user's TokensValidFrom date, usually after a password change, reset or admin session revocation. After an incident it is the row you want: each client still holding an old token, attacker included, fails with 50173 in AADNonInteractiveUserSignInLogs, exposing its IP and device. **Fix:** User: sign in again; each app will prompt once. Admin, after a compromise: reset the password if the attacker may know it, revoke sessions (`Revoke-MgUserSignInSession`), then treat every 50173 from an IP or device you can't tie to the user as an attacker indicator. | Field | Value | |---|---| | Code | AADSTS50173 | | Microsoft name | Grant expired due to revocation | | Category | Tokens and sessions | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1550.001](https://attack.mitre.org/techniques/T1550/001/) Use Alternate Authentication Material: Application Access Token | | Where to look | `AADNonInteractiveUserSignInLogs`, `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS50173 mean? Microsoft's description: > The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. The grant was issued on '{authTime}' and the TokensValidFrom date (before which tokens are not valid) for this user is '{validDate}'. Microsoft's troubleshooting article lists three causes: *"The user changes or resets their password. The refresh token expires. An administrator revokes the refresh token."* The client tried to redeem a refresh token that was issued before the user's `TokensValidFrom` date. The token is dead. The client has to send the user through an interactive sign-in again. ## Reproduced in the lab On 30 October 2026 an automated lab run did this, in order: 1. Signed a test user in and kept the refresh token. 2. Used that refresh token. **It worked**, and returned a new access token. That is the control. 3. Called `POST /users/{id}/revokeSignInSessions` on Microsoft Graph, which is what the Entra admin center's **Revoke sessions** button does. 4. Waited two minutes, then used a refresh token from before the revocation again. The fourth step returned `AADSTS50173`: > AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. Two things that are useful when you are working an incident. The control step matters: the same token worked minutes earlier, so a 50173 is evidence that the revocation reached that token, not that the token was always bad. And the message blames a password change even when the admin only revoked sessions, so **do not read "the user might have changed or reset their password" as proof that a password change happened**. Revocation and password change produce the same wording here. The sign-in log row isn't captured yet; see [how pages are checked](https://brambrinkmeier.com/methodology/). In the lab tenant's sign-in logs, the test user's refresh-token activity shows up under **User sign-ins (non-interactive)**, not the interactive table, with the resource **Microsoft Graph** and Conditional Access **Not Applied**. Two grouped rows appeared for that user and resource: one Failure, and one Success with a count of 2. That matches the run (one failed replay after revocation, two successful token uses before it), but the portal's non-interactive view groups rows and doesn't show the error code, so the failure row is consistent with the 50173 rather than confirmed as it from the portal alone. The grouping is the practical lesson: non-interactive rows are aggregated when user, app, IP, status and resource match, so a row count in that table is not a request count. Use the `# sign ins` value, or the equivalent field in your workspace, before you treat a number as a number of attempts. ## Is it an attack? See the [comparison of the codes behind "asked to sign in again"](https://brambrinkmeier.com/guides/why-user-asked-to-sign-in-again-entra-id/) (70043, 700082, 50173, 50133, 50076). Usually not. A password change makes every device the user owns hit 50173 once, and then the user signs in again. **The security value is during incident response.** When you revoke a compromised user's sessions with `Revoke-MgUserSignInSession` or **Revoke sessions** in the admin center, the Graph call *"Invalidates all the refresh tokens issued to applications for a user (and session cookies in a user's browser), by resetting the signInSessionsValidFromDateTime user property to the current date-time"*, with *"a small delay of a few minutes"* possible. Microsoft's revoke-access procedure (in Microsoft Entra ID: disable the user, revoke refresh tokens, disable devices; in a hybrid environment it first disables the user and resets the password twice in on-premises Active Directory) says that after those steps *"the user can't gain new tokens for any application tied to Microsoft Entra ID."* Revocation on its own doesn't stop someone who still knows the password from signing in again. Every client that still holds a refresh token for that user fails on its next refresh. That includes the attacker's client. Each of those failures should appear as a 50173 row with an IP address, a user agent and device details (my reasoning, not yet checked in a lab). **IP caveat for confidential clients.** Microsoft's [non-interactive sign-ins page](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) says: *"The IP address of non-interactive sign-ins performed by confidential clients doesn't match the actual source IP of where the refresh token request is coming from. Instead, it shows the original IP used for the original token issuance."* So for those apps the IP on a 50173 row may be where the token was first issued, not where the attacker is now. Weigh it with the user agent and device details. | Pattern after a revocation or password reset | Likely meaning | |---|---| | 50173 from the user's own managed devices and usual IPs | The legitimate user's apps being signed out. Expected. | | 50173 from an IP, country or device you can't tie to the user | A client you didn't know about was holding a token. Treat it as the attacker's session and pivot on that IP. | | 50173 rows continue from the same unknown IP, followed by interactive attempts (`SigninLogs`) | The attacker is trying to get back in with credentials. Check the password was actually changed and MFA methods are clean. | | No 50173 at all after the revocation | Nothing was refreshing a token for that user in the window you looked at. Not proof that nothing was ever stolen. | Two reading notes: - The `TokensValidFrom` date in the message is the cut-off set by the revocation or password change. Tokens issued before it are refused. - Revocation only stops **new** tokens. Microsoft notes that *"By default, access tokens issued by Microsoft Entra ID last for 1 hour."* (Microsoft's token lifetime reference gives the default more precisely as a random value between 60 and 90 minutes.) An attacker can keep using an access token they already have until it expires, and you won't see a 50173 for that period. The exception is Continuous Access Evaluation: Microsoft's CAE page says the implementation *"focuses on Exchange, Teams, and SharePoint Online"* and needs a CAE-capable client. There, an admin revocation or password change is enforced on the access token before it expires, with *"latency of up to 15 minutes"*. CAE access tokens themselves are long-lived, *"up to 28 hours"*, and *"If you aren't using CAE-capable clients, your default access token lifetime remains 1 hour."* The [session revocation guide](https://brambrinkmeier.com/guides/revoke-sessions-and-verify-entra-id/) covers this and how to prove the cut-off. ## How do I find it in my logs (KQL)? Who was still holding a token for this user after you revoked it? Set the user and the time you revoked. ```kusto let revokedUser = "{user-principal-name}"; let revokedAt = datetime(2026-10-11T09:00:00Z); AADNonInteractiveUserSignInLogs | where TimeGenerated > revokedAt | where UserPrincipalName =~ revokedUser | where ResultType == "50173" | extend Device = parse_json(DeviceDetail), Location = parse_json(LocationDetails) | summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Rows = count(), Apps = make_set(AppDisplayName, 10) by IPAddress, Country = tostring(Location.countryOrRegion), City = tostring(Location.city), OS = tostring(Device.operatingSystem), Browser = tostring(Device.browser), DeviceId = tostring(Device.deviceId), IsManaged = tostring(Device.isManaged), IsCompliant = tostring(Device.isCompliant), UserAgent | sort by FirstSeen asc ``` `DeviceDetail` and `LocationDetails` are **strings** in `AADNonInteractiveUserSignInLogs` (they are dynamic in `SigninLogs`), so they need `parse_json` before you can read their fields. The JSON field names above follow the Microsoft Graph `signIn` resource; check them against a row in your own workspace. Non-interactive rows are **aggregated** when application, user, IP address, status and resource match, so `Rows` is a count of log rows, not of refresh attempts. Then take every IP from that result that isn't the user's and see what else it touched, across all users: ```kusto let suspectIPs = dynamic(["{ip-address}"]); union (SigninLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType, AppDisplayName, Table = "Interactive"), (AADNonInteractiveUserSignInLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType, AppDisplayName, Table = "NonInteractive") | where TimeGenerated > ago(14d) | where IPAddress in (suspectIPs) | summarize Users = make_set(UserPrincipalName, 20), Results = make_set(ResultType, 20), Apps = make_set(AppDisplayName, 20), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by IPAddress, Table ``` `ResultType` is a **string** column, so compare it with `"50173"`, not `50173`. ## How do Conditional Access and MFA affect it? - Revocation works independently of Conditional Access. No policy has to match for a 50173 to happen. - After a 50173 the client needs a fresh interactive sign-in. That new sign-in goes through the password check, MFA and your Conditional Access policies again. That is the point: an attacker with a stolen refresh token but without the password and the MFA factor can't get past it. - If the attacker also has the password, revocation alone isn't enough: it ends their current sessions, but they can sign in again interactively, and if they registered their own MFA method they will pass that step too. Reset the password and check the user's registered MFA methods in the same response. ## How do I fix AADSTS50173? **For the user:** sign in again. Each app will prompt once. **For admins (incident response):** 1. Reset the password if it may be known to the attacker. Microsoft's Entra steps don't include a password reset; its hybrid procedure resets the on-premises password (twice) before revoking in Entra ID. Resetting first in a cloud-only tenant is our recommendation, so a new sign-in can't slip in between. 2. Revoke the user's sessions: `Revoke-MgUserSignInSession -UserId $User.Id`, or **Revoke sessions** on the user's Overview page. 3. Microsoft's revoke-access guidance also disables the user's devices (`Update-MgDevice -DeviceId -AccountEnabled:$false`). Do that for devices you suspect. 4. Run the first query above for the time after the revocation. Every 50173 from an IP or device you can't tie to the user is an attacker indicator. Block it and hunt it across other accounts with the second query. 5. Remember the access-token window: allow for up to 90 minutes of continued access after revocation for clients and resources without Continuous Access Evaluation, and about 15 minutes for Exchange, SharePoint and Teams through CAE-capable clients. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Refresh token replayed after an admin revoked the user's sessions, against a lab tenant; scenario: Refresh token after the admin revoked sessions). First line returned: > AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. Lab-run rows naming this code (12; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-30 | Refresh token after the admin revoked sessions | 50173 / 700082 / 50076 | 50173 | AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. The gran | | 2026-10-30 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-31 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-31 | Refresh token after the admin revoked sessions | 50173 / 700082 / 50076 | 50173 | AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. The gran | | 2026-10-31 | Must change password at next sign-in | 50055 / 50144 / 50173 | 50055 | AADSTS50055: The password is expired. | | 2026-10-31 | Refresh token after the admin revoked sessions | 50173 / 700082 / 50076 | 50173 | AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. The gran | ## Sources 1. [Access tokens in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens) 2. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 3. [Error AADSTS50173 - The provided grant has expired due to it being revoked](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50173-grant-expired-revoked) 4. [Revoke user access in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/users/users-revoke-access) 5. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 6. [Microsoft Graph: user: revokeSignInSessions](https://learn.microsoft.com/en-us/graph/api/user-revokesigninsessions) 7. [Continuous access evaluation](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-continuous-access-evaluation) 8. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadnoninteractiveusersigninlogs) ## Related codes [AADSTS50133](https://brambrinkmeier.com/entra/aadsts/50133/), [AADSTS70043](https://brambrinkmeier.com/entra/aadsts/70043/), [AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS135011](https://brambrinkmeier.com/entra/aadsts/135011/), [AADSTS50057](https://brambrinkmeier.com/entra/aadsts/50057/), [AADSTS50089](https://brambrinkmeier.com/entra/aadsts/50089/), [AADSTS50140](https://brambrinkmeier.com/entra/aadsts/50140/), [AADSTS70008](https://brambrinkmeier.com/entra/aadsts/70008/), [AADSTS500341](https://brambrinkmeier.com/entra/aadsts/500341/), [AADSTS700003](https://brambrinkmeier.com/entra/aadsts/700003/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50173: Grant expired because it was revoked", https://brambrinkmeier.com/entra/aadsts/50173/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50194/ # AADSTS50194 fix: single-tenant app used the /common endpoint Canonical: https://brambrinkmeier.com/entra/aadsts/50194/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50194.json **Short answer:** AADSTS50194 means a single-tenant app registration sent its sign-in to the /common endpoint, which Microsoft Entra ID doesn't allow for single-tenant apps created after a cut-off date. It is a configuration error with low attack value. Fix it by putting your tenant ID in the app's authority URL, or make the app multitenant if it really must serve other tenants. **Fix:** Developer or admin: replace `/common` in the app's sign-in URL or tenant setting with your tenant ID or domain. Only switch the app registration to multitenant (Authentication > Supported account types) if users from other organizations must sign in. User: report it to whoever runs the app. | Field | Value | |---|---| | Code | AADSTS50194 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS50194 mean? Microsoft's description: > Application '{appId}'({appName}) isn't configured as a multitenant application. Usage of the /common endpoint isn't supported for such applications created after '{time}'. Use a tenant-specific endpoint or configure the application to be multitenant. The reference table gives this code no PascalCase name. Every sign-in URL has a tenant part: `https://login.microsoftonline.com//oauth2/v2.0/authorize`. Microsoft's protocol overview lists the allowed values: `common` for work, school and personal Microsoft accounts, `organizations` for work or school accounts only, `consumers` for personal accounts only, and *"tenant identifiers such as the tenant ID or domain name"*. `/common` tells Entra "I don't know the user's tenant yet". That only makes sense for an app that accepts users from any tenant. App registrations are single-tenant by default: Microsoft's conversion guide says *"web app/API registrations in Microsoft Entra ID are single-tenant upon creation"*. When such an app sends its users to `/common`, Entra returns 50194. The `{time}` placeholder is filled in the real message. Users on the UiPath forum report the text *"created after '10/15/2018'"*. By the message's own wording, single-tenant apps created before that date are not covered. Our reading: that is why an integration that worked for years can fail once someone sets it up again with a new app registration. Who hits it, from user reports: SaaS connectors and automation tools that default to `/common`, such as WP Mail SMTP's Outlook mailer and the UiPath Microsoft 365 activities, and custom apps that copied a `/common` sample. Related codes with their own page: - [90133](https://brambrinkmeier.com/entra/aadsts/90133/): a device code request on `/common` or `/consumers`. Same family of problem, a specific flow. - [700016](https://brambrinkmeier.com/entra/aadsts/700016/): the app isn't found in the tenant at all. That is what you get when you point the app at the **wrong** tenant ID. - [90002](https://brambrinkmeier.com/entra/aadsts/90002/): the tenant name or ID in the URL doesn't exist. ## Is it an attack? No. The app is set up wrong, and the error is Entra enforcing the app's own setting. A request to `/common` for a single-tenant app gets no token. | Pattern | Likely meaning | |---|---| | Every user of one app, starting the day it went live | The app or connector uses `/common` by default and the app registration is single-tenant. Fix the authority. | | Started after someone created a new app registration for an existing integration | The new registration falls under the cut-off date in the message, the old one didn't. Likely, but unconfirmed. | | A few users of a multitenant SaaS app | Not this code's pattern. Look at [50020](https://brambrinkmeier.com/entra/aadsts/50020/) or [16000](https://brambrinkmeier.com/entra/aadsts/16000/) instead. | ## How do I find it in my logs (KQL)? Microsoft doesn't document whether 50194 is written to the sign-in logs, or in which tenant: the request names no tenant, so it is not obvious whose log would get the row. Check your workspace first: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "50194" | summarize Rows = count() by SourceTable ``` If rows exist, find the apps that send `/common` requests. The app ID is in the error text as well as in `AppId`: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "50194" | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppId, AppDisplayName, ResourceTenantId | sort by Rows desc ``` If the union returns nothing, take the app ID from the error message the user saw. `ResultType` is a **string** column, so compare it with `"50194"`, not `50194`. ## How do I fix AADSTS50194? **For the user:** nothing on your side. Send the full error message to whoever runs the app; it names the app ID. **For developers:** 1. Keep the app single-tenant and use a tenant-specific authority: `https://login.microsoftonline.com//` instead of `.../common/`. The error message offers this first. Microsoft's registration quickstart says *"We recommend Single tenant only - for most applications."* 2. Microsoft's protocol overview accepts either *"the tenant ID or domain name"* there. 3. In third-party tools, look for a "Tenant", "Tenant ID" or "Directory ID" field. A UiPath forum post suggests setting the Tenant parameter of the Microsoft 365 activities; nobody in that thread confirmed it worked. **For admins:** 1. Only make the app multitenant if people from other organizations really need it. Microsoft's steps: open the app registration, **Authentication**, **Supported account types**, and choose **Accounts in any organizational directory**. In the manifest that is `signInAudience` = `AzureADMultipleOrgs` instead of `AzureADMyOrg`. 2. Know what that switch does. Microsoft describes multitenant as *"when you want users in any Microsoft Entra tenant to be able to use your application"*. Some vendor guides, such as WP Mail SMTP's, tell you to switch to multitenant plus personal accounts. Our view: for an internal mail or automation app, the tenant-ID fix gives the same result without opening the app to other tenants. 3. If the switch fails, check the Application ID URI. Microsoft says that for multitenant apps it must be globally unique, and *"if the App ID URI doesn't follow this pattern, setting an application as multitenant fails."* ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. Lab-run rows naming this code (14; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [OAuth 2.0 and OpenID Connect (OIDC) in the Microsoft identity platform](https://learn.microsoft.com/en-au/entra/identity-platform/v2-protocols) 3. [Convert single-tenant app to multitenant on Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity-platform/howto-convert-app-to-be-multi-tenant) 4. [Quickstart: Register an application with the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) 5. [Validation differences by supported account types (signInAudience)](https://learn.microsoft.com/entra/identity-platform/supported-accounts-validation) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 7. [Microsoft Q&A: Can't authenticate applications registered in Azure](https://learn.microsoft.com/en-us/answers/questions/22428/cant-authenticate-applications-registered-in-arure) 8. [UiPath forum: Microsoft Office 365 throws error AADSTS50194](https://forum.uipath.com/t/microsoft-office-365-throws-error-aadsts50194-application-is-not-configured-as-a-multi-tenant-application/399812) 9. [WP Mail SMTP: invalid_request AADSTS50194](https://wpmailsmtp.com/docs/smtp-error-invalid_request-aadsts50194/) ## Related codes [AADSTS90133](https://brambrinkmeier.com/entra/aadsts/90133/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS9002331](https://brambrinkmeier.com/entra/aadsts/9002331/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50194 fix: single-tenant app used the /common endpoint", https://brambrinkmeier.com/entra/aadsts/50194/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/50196/ # AADSTS50196: App is stuck in a sign-in loop (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/50196/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50196.json **Short answer:** AADSTS50196 means Entra detected a client loop: the app sent the same request too many times in a short period. Microsoft says the usual cause is missing or broken token caching. It points to a faulty app, not usually to an attacker. The fix is in the app: cache tokens, call the silent method first, and stop retrying on errors. **Fix:** Developer: set up token caching, call `AcquireTokenSilent` before any interactive call, don't retry in a tight loop, and honour `Retry-After` for app-only tokens. User: close the app or tab and reopen it, or sign out and back in. If it keeps happening, report it to the app owner. | Field | Value | |---|---| | Code | AADSTS50196 | | Microsoft name | LoopDetected | | Category | Tokens and sessions | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs`, `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS50196 mean? Microsoft's description: > **LoopDetected**: A client loop has been detected. Check the app’s logic to ensure that token caching is implemented, and that error conditions are handled correctly. The app has made too many of the same request in too short a period, indicating that it is in a faulty state or is abusively requesting tokens. Entra is throttling one client. The app asked for the same token over and over, and Entra stopped answering it with tokens. Microsoft's MSAL.NET throttling page says when this happens: *"Microsoft Entra ID throttles applications when you call the authentication API too frequently. Most often this happens when token caching is not used."* It also says how it shows up. For user-facing calls, the app gets an `invalid_grant` error with the message *"AADSTS50196: The server terminated an operation because it encountered a loop while processing a request"*. For the client credentials grant (app-only tokens), Entra replies with `429 Too Many Requests` and a `Retry-After: 60` header instead. Our reading: an app-only loop may therefore not show up as 50196 at all, but as throttling with no AADSTS code in the client. ## Is it an attack? Usually not. Microsoft's description allows two readings: the app *"is in a faulty state or is abusively requesting tokens."* In practice the first is far more common, and the cause sits in the app's code. | Pattern | Likely meaning | |---|---| | One app, many users, starting on the day of a release | A bug in the new version: token cache broken, or a retry loop. | | One user, one app, one device | That device's token cache is broken or the app is stuck after an error. Often a browser tab or desktop client stuck in a redirect loop. | | A script or tool (PowerShell, CLI, a sync job) | The script asks for a new token on every call instead of reusing one. | | One IP, many users, an app you don't recognise | Worth a look, though Microsoft doesn't describe this case. It could be an automated tool replaying tokens at scale. Check what else that IP did. | Most likely, 50196 is a symptom of request volume, not of a credential being guessed: the user was already signed in. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 50196 is logged in. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "50196" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which apps, users and clients loop: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "50196" | summarize Rows = count(), Users = dcount(UserPrincipalName), IPs = dcount(IPAddress), Agents = make_set(UserAgent, 5), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppDisplayName, AppId, ResourceDisplayName | sort by Rows desc ``` A new looping app or a sudden spike. This compares the last day with the 14 days before it: ```kusto let recent = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "50196" | summarize RecentRows = count(), RecentUsers = dcount(UserPrincipalName) by AppId, AppDisplayName; let baseline = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated between (ago(15d) .. ago(1d)) | where ResultType == "50196" | summarize BaselineRows = count() by AppId; recent | join kind=leftouter baseline on AppId | extend BaselineRows = coalesce(BaselineRows, 0) | where BaselineRows == 0 or RecentRows > 3 * (BaselineRows / 14.0) | project AppDisplayName, AppId, RecentRows, RecentUsers, BaselineRows | sort by RecentRows desc ``` The factor of 3 is a starting point. Non-interactive rows are aggregated when application, user, IP address, status and resource ID match, so a single row can stand for many requests. Count rows to compare apps, not to count requests. ## How do I fix AADSTS50196? **For the user:** close the app or browser tab completely and open it again. If that doesn't help, sign out of the app, clear its cached sign-in, and sign in again. If it keeps happening, report it to whoever runs the app; the fix is in the app. **For developers:** Microsoft's throttling page lists the usual causes: 1. *"Token caching is not setup correctly."* 2. Not calling the silent method (`AcquireTokenSilent`) before an interactive or username/password call. 3. Asking for a scope that doesn't apply to personal Microsoft accounts, such as `User.ReadBasic.All`, *"resulting in cache misses."* Reuse tokens until they are close to expiry. Don't retry in a tight loop when a call fails. For app-only tokens, honour the `Retry-After` header. MSAL throws `MsalThrottledServiceException` or `MsalThrottledUiRequiredException` when it throttles on the client side; the page notes that *"If MSAL would not apply client-side throttling the application would still not be able to acquire tokens."* **For admins:** 1. Use the second query to find the app, then give its owner the time window and the user agents. 2. If it is a script running under a user account, check that it gets one token and reuses it. 3. If an unknown app or a single IP produces 50196 for many users, look at that IP's other sign-ins before you close it as a bug. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Client and server throttling (MSAL.NET)](https://learn.microsoft.com/en-us/entra/msal/dotnet/advanced/client-and-server-throttling) 3. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/), [AADSTS70043](https://brambrinkmeier.com/entra/aadsts/70043/), [AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS54005](https://brambrinkmeier.com/entra/aadsts/54005/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS50196: App is stuck in a sign-in loop (fix)", https://brambrinkmeier.com/entra/aadsts/50196/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/51004/ # AADSTS51004 fix: user account not in the directory Canonical: https://brambrinkmeier.com/entra/aadsts/51004/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/51004.json **Short answer:** AADSTS51004 means the signing-in user has no account in the tenant the app chose. Microsoft says the app likely picked the wrong tenant; if the user should have access, add them as a guest. Users also report it with federated sign-in (Okta, Google Workspace) when the identity from the IdP matches no Entra user. Low attack value. **Fix:** User: check you are signed in with the right account and opening your organisation's link, not another tenant's. Admin: if the user should have access, invite them as a guest (B2B). With federation, check the user exists in Entra ID and that their ImmutableId matches what the IdP sends. | Field | Value | |---|---| | Code | AADSTS51004 | | Microsoft name | UserAccountNotInDirectory | | Category | Guests and tenants | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS51004 mean? Microsoft's description: > **UserAccountNotInDirectory**: The user account doesn’t exist in the directory. An application likely chose the wrong tenant to sign into, and the currently logged in user was prevented from doing so since they did not exist in your tenant. If this user should be able to log in, add them as a guest. For further information, please visit add B2B users. The user is known somewhere, but not in the tenant this sign-in went to. Microsoft's first guess is an app that sent the user to the wrong tenant. The message users see reads like this example from Microsoft Q&A: *"AADSTS51004: The user account {id} does not exist in the {tenant ID} directory. To sign into this application, the account must be added to the directory."* The tenant ID in the message tells you which directory was asked. ### 51004 or 50034? The wording is almost the same, so the code is what tells them apart. [50034](https://brambrinkmeier.com/entra/aadsts/50034/) (*UserAccountNotFound*) is the one Microsoft ties to a mistyped username. When a token request was sent for a username that doesn't exist in a lab tenant, Entra returned 50034, not 51004 (see the 50034 page). Microsoft's 51004 description talks about *"the currently logged in user"*. Our reading: 51004 tends to come after the user has already been identified, by their home tenant or by a federated identity provider, and Entra then can't find a matching account in the target tenant. 50034 is the plain "no such username" answer. Microsoft doesn't document the split in those words. [50020](https://brambrinkmeier.com/entra/aadsts/50020/) is a close neighbour too: an account from another identity provider that isn't a user or guest in the tenant. Both point to the same fix for outside users: add them as a guest. ## Is it an attack? Usually not. Our reading: the user has already proven who they are somewhere; they just aren't in this directory. | Pattern | Likely meaning | |---|---| | A user from another organisation opening your app, or Teams switching into your tenant | Wrong tenant or no guest account. Users report this often in Teams and other Microsoft 365 apps. Benign. Invite them as a guest if they need access. | | Users of a federated domain (Okta, Google Workspace, other SAML IdP) failing after the IdP login | The IdP authenticated them, but no Entra user matches what the IdP sent. Okta and Microsoft Q&A users report this. A provisioning or ImmutableId problem, not an attack. | | New hires failing while existing users work, on a federated domain | The account was created at the IdP but never provisioned to Entra ID. | | A former employee or a renamed user | Something still uses the old identity. Find and update it. | Unlike [50034](https://brambrinkmeier.com/entra/aadsts/50034/), there is no documented enumeration pattern for 51004. Our reading is that it has low value for an attacker testing usernames, because it follows a sign-in that already happened somewhere else. A burst of 51004 for many different users from one IP is still worth a look; the KQL below finds it. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 51004 lands in. Check where it lands: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "51004" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Which apps send users to a tenant they're not in, and where the users come from: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "51004" | summarize Rows = count(), Users = dcount(UserPrincipalName), SampleUsers = make_set(UserPrincipalName, 10), HomeTenants = make_set(HomeTenantId, 5), Protocols = make_set(AuthenticationProtocol, 3) by AppDisplayName, AppId | sort by Users desc ``` Many different accounts from one IP, the shape worth a second look (10 is a starting point; tune it to your tenant): ```kusto SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "51004" | summarize Accounts = dcount(UserPrincipalName), Attempts = count(), Sample = make_set(UserPrincipalName, 20) by IPAddress | where Accounts >= 10 | sort by Accounts desc ``` For a user who doesn't exist in the tenant, which column holds the name is not documented. `UserPrincipalName` is a reasonable first guess; also check `SignInIdentifier`. A federated domain with many 51004 rows from your own egress IPs points at provisioning, not an attacker. `ResultType` is a **string** column, so compare it with `"51004"`. ## How does Conditional Access affect it? - Our reading: Conditional Access plays no part, because there is no user object in the tenant for a policy to match. - If the user is later added as a guest, the target tenant's Conditional Access policies apply to them from then on. ## How do I fix AADSTS51004? **For the user:** check that you are signed in with the right account. In Teams or a browser with several accounts, sign out and sign in again with the account your organisation gave you. If you are from another organisation, ask the app owner to invite you as a guest. **For developers:** check which tenant your app sends users to. Likely, but not documented: an app hard-wired to one tenant ID sends outside users there, and they fail. Use the tenant the user belongs to, or ask the tenant owner to invite them. **For admins:** 1. External user who needs access: add them as a guest, as Microsoft's description says. In the Entra admin center (at least User Administrator): **Users** > **New user** > **Invite external user**. Microsoft notes *"The guest user must then redeem their invitation to access resources."* 2. Federated domain (Okta, Google Workspace, other SAML IdP): the user must exist in Entra ID first. Microsoft's federated sign-in docs for Windows devices state that *"each Google Workspace user requires a matching account defined in Microsoft Entra ID"*, and that Entra *"searches for a matching user object in the tenant by using an attribute called ImmutableId"*. The match is case-sensitive. Check the account exists and that its `OnPremisesImmutableId` matches what the IdP sends. Okta's KB describes this exact mismatch as a cause of 51004. 3. New users failing only: check provisioning from the IdP actually created them in Entra ID. 4. Renamed or removed user: find what still uses the old identity and update it. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Add Microsoft Entra B2B collaboration users in the Microsoft Entra admin center](https://learn.microsoft.com/en-us/entra/external-id/add-users-administrator) 3. [Configure federated sign-in for Windows devices (identity matching in Microsoft Entra ID)](https://learn.microsoft.com/en-us/education/windows/federated-sign-in#identity-matching-in-microsoft-entra-id) 4. [Configure federation between Google Workspace and Microsoft Entra ID](https://learn.microsoft.com/en-us/education/windows/configure-aad-google-trust) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 6. [Microsoft Q&A: AADSTS51004 the user account does not exist in the directory (user report)](https://learn.microsoft.com/en-us/answers/questions/1581749/aadsts51004-the-user-account-it-does-not-exist-in) 7. [Okta KB: AADSTS51004 during Microsoft Office 365 single sign-on (vendor KB)](https://support.okta.com/help/s/article/error-during-microsoft-office-365-single-sign-on-aadsts51004-the-user-account-does-not-exist-in-the-directory) 8. [Windows Report: AADSTS51004 error on Teams (user reports)](https://windowsreport.com/aadsts51004-teams-error/) ## Related codes [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/), [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS90072](https://brambrinkmeier.com/entra/aadsts/90072/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS51004 fix: user account not in the directory", https://brambrinkmeier.com/entra/aadsts/51004/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/53000/ # AADSTS53000: Device not compliant Canonical: https://brambrinkmeier.com/entra/aadsts/53000/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/53000.json **Short answer:** AADSTS53000 means a Conditional Access policy requires a compliant device and the device signing in isn't compliant. The password was already accepted. Usually it is a user on a personal or unenrolled device. For a privileged account on a new device or IP, treat it as a valid credential in the wrong hands. **Fix:** User: enroll the device with your organisation's MDM (for example Intune). If it's already enrolled, ask IT which compliance setting is failing. Admin: fix the device's compliance rather than adding an exclusion. If the device is unknown and the IP unfamiliar, reset the password and revoke sessions. | Field | Value | |---|---| | Code | AADSTS53000 | | Microsoft name | DeviceNotCompliant | | Category | Devices | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts, [T1557](https://attack.mitre.org/techniques/T1557/) Adversary-in-the-Middle, [T1539](https://attack.mitre.org/techniques/T1539/) Steal Web Session Cookie | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS53000 mean? Microsoft's description: > **DeviceNotCompliant**: Conditional Access policy requires a compliant device, and the device isn't compliant. The user must enroll their device with an approved MDM provider like Intune. For additional information, please visit Conditional Access device remediation. Conditional Access only evaluates after the first factor succeeds. So a 53000 row means the username and password (and any earlier step) were accepted, and the device grant control is what stopped the sign-in. `ConditionalAccessStatus` on these rows is `failure`. ## Is it an attack? Usually not. Most 53000 rows are users on a personal laptop or phone, a new device that hasn't finished Intune enrollment, or a device that has drifted out of compliance. The security reading comes from what the code proves: **someone with a working credential tried to use it from a device you don't manage.** That is exactly what an attacker's machine looks like. | Pattern | Likely meaning | |---|---| | Known user, known device, compliance recently lapsed | Benign. Fix the device. | | New user onboarding, first days | Benign. Device not enrolled yet. | | Privileged account, device never seen before, unfamiliar IP or country | **Investigate.** The credential works and is being used off-estate. | | 53000 shortly after a phishing click, or after 50126 failures from the same IP | **Treat the password as compromised.** | | 53000 in non-interactive logs from an unexpected IP | A refresh token being redeemed from an unmanaged device. Possible token replay (reasoning, not a Microsoft statement). | Why it matters: an adversary-in-the-middle phishing kit can capture a password, the MFA result and the session cookie, but it runs on the attacker's infrastructure, not on an enrolled device. A compliant-device requirement is one of the controls that still holds after MFA is phished. A 53000 from a source that isn't the user, for an account that otherwise passed MFA, is that control working, and a reason to ask how the earlier layers were passed. ## How do I find it in my logs (KQL)? Who is hitting the compliant-device requirement, and from which devices: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "53000" | extend DeviceId = tostring(DeviceDetail.deviceId), DeviceName = tostring(DeviceDetail.displayName), OS = tostring(DeviceDetail.operatingSystem), TrustType = tostring(DeviceDetail.trustType), IsCompliant = tostring(DeviceDetail.isCompliant), Country = tostring(LocationDetails.countryOrRegion) | summarize Attempts = count(), IPs = make_set(IPAddress, 10), Countries = make_set(Country, 5), Apps = make_set(AppDisplayName, 5) by UserPrincipalName, DeviceId, DeviceName, OS, TrustType, IsCompliant | sort by Attempts desc ``` An empty `DeviceId` means the device isn't registered in Entra at all, which is the more interesting case for an attacker machine. An unregistered device was blocked, then the **same user from the same IP** succeeded somewhere else on the same day. That can mean the credential reached an app or client the device policy doesn't cover: ```kusto let blocked = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "53000" | where isempty(tostring(DeviceDetail.deviceId)) | summarize BlockedIPs = make_set(IPAddress) by UserPrincipalName; SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "0" | join kind=inner blocked on UserPrincipalName | where set_has_element(BlockedIPs, IPAddress) | project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, ClientAppUsed, ConditionalAccessStatus, DeviceDetail | sort by TimeGenerated asc ``` Run the first query against `AADNonInteractiveUserSignInLogs` as well. There `DeviceDetail` and `LocationDetails` are **string** columns, so wrap them: `parse_json(DeviceDetail).deviceId`. The `DeviceDetail` property names above (`deviceId`, `displayName`, `operatingSystem`, `trustType`, `isCompliant`) follow the Microsoft Graph `signIn` device detail object. Check them against one row in your own workspace before building a rule on them. ## How does Conditional Access affect it? - 53000 is produced **by** Conditional Access. Open the sign-in, select the **Conditional Access** tab, and Microsoft's troubleshooting guide says it "shows the specific policy or policies that resulted in the sign-in interruption." - A policy that requires a compliant device only protects the apps and users it targets. Excluded apps, excluded users and report-only policies are where a stolen credential still works. - A policy that accepts a compliant device **or** MFA as alternatives lets a phished MFA result satisfy it. For admin accounts, require the device control on its own. ## How do I fix AADSTS53000? **For the user:** enroll the device with your organization's MDM (for example Intune). If it is already enrolled, ask IT which compliance setting is failing. **For admins:** 1. Open the failed sign-in and confirm which policy and which device it was. Compare the device ID with the user's enrolled devices. 2. If the device is unknown and the account is privileged or the IP is unfamiliar, treat the password as compromised: reset it, revoke sessions (`Revoke-MgUserSignInSession`) and review recent sign-ins for the same IP. 3. If it is a real user on a real device, fix compliance rather than adding an exclusion. Every exclusion is a path for a stolen credential. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Troubleshoot sign-in problems with Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/troubleshoot-conditional-access) 3. [Sign-in log activity details](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-in-log-activity-details) 4. [signIn resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/signin) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS53001](https://brambrinkmeier.com/entra/aadsts/53001/), [AADSTS50097](https://brambrinkmeier.com/entra/aadsts/50097/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS135011](https://brambrinkmeier.com/entra/aadsts/135011/), [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50155](https://brambrinkmeier.com/entra/aadsts/50155/), [AADSTS530002](https://brambrinkmeier.com/entra/aadsts/530002/), [AADSTS530003](https://brambrinkmeier.com/entra/aadsts/530003/), [AADSTS530004](https://brambrinkmeier.com/entra/aadsts/530004/), [AADSTS530031](https://brambrinkmeier.com/entra/aadsts/530031/), [AADSTS530032](https://brambrinkmeier.com/entra/aadsts/530032/), [AADSTS700003](https://brambrinkmeier.com/entra/aadsts/700003/), [AADSTS5000611](https://brambrinkmeier.com/entra/aadsts/5000611/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS53000: Device not compliant", https://brambrinkmeier.com/entra/aadsts/53000/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/53001/ # AADSTS53001: Device not domain joined Canonical: https://brambrinkmeier.com/entra/aadsts/53001/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/53001.json **Short answer:** AADSTS53001 means a Conditional Access policy requires a domain-joined (hybrid joined) device and the device signing in isn't one. The password was already accepted. Usually it is a user on a personal or cloud-only device. From an unknown device on an unfamiliar IP, it means a working credential is being used outside your estate. **Fix:** User: sign in from your corporate, domain-joined computer. If you're already on one, ask IT to check its join to Entra ID has completed. Admin: for a legitimate cloud-joined device, let the policy accept compliant devices too. Unknown device and unfamiliar IP: reset the password, revoke sessions. | Field | Value | |---|---| | Code | AADSTS53001 | | Microsoft name | DeviceNotDomainJoined | | Category | Devices | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS53001 mean? Microsoft's description: > **DeviceNotDomainJoined**: Conditional Access policy requires a domain joined device, and the device isn't domain joined. Have the user use a domain joined device. Most likely (interpretation) this is the Conditional Access grant control that requires a hybrid joined device (on-premises domain joined and registered in Entra ID). Conditional Access only runs after the first factor succeeds, so the credential was accepted before this block. `ConditionalAccessStatus` on these rows is `failure`. ## Is it an attack? Usually not. Typical causes are a user on a home PC or phone, an Entra-joined (cloud-only) laptop hitting a policy written for hybrid-joined machines, or a hybrid join that hasn't finished syncing. The security reading is the same as 53000 (non-compliant device): the code proves **a working credential was used from a device that isn't one of yours.** | Pattern | Likely meaning | |---|---| | Known user, Entra-joined corporate device | Benign. Policy expects hybrid join; device is cloud-joined. | | New device, hybrid join pending | Benign. Wait for sync or check the join state. | | Unregistered device (empty device ID), unfamiliar IP or country | **Investigate.** Someone has the password and is using it off-estate. | | 53001 after a 50126 run from the same IP | **The spray found a correct password.** The device policy is the only thing that stopped it. | A device-based grant is a strong control against stolen credentials and against adversary-in-the-middle phishing, because the attacker's machine is not joined to your domain. When a 53001 row shows `AuthenticationRequirement` as `multiFactorAuthentication` and the MFA step as satisfied, the password and MFA layers were already passed and the device requirement was the only layer that held. For a legitimate user on a personal device that is friction; for an unknown device on an unfamiliar IP it means the earlier layers didn't stop whoever holds the credential. ## How do I find it in my logs (KQL)? 53001 from devices that aren't registered in Entra at all: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "53001" | extend DeviceId = tostring(DeviceDetail.deviceId), TrustType = tostring(DeviceDetail.trustType), OS = tostring(DeviceDetail.operatingSystem), Country = tostring(LocationDetails.countryOrRegion) | summarize Attempts = count(), IPs = make_set(IPAddress, 10), Countries = make_set(Country, 5), Apps = make_set(AppDisplayName, 5), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by UserPrincipalName, DeviceId, TrustType, OS | extend Unregistered = isempty(DeviceId) | sort by Unregistered desc, Attempts desc ``` Did the same IP fail passwords first? That pattern means a spray succeeded: ```kusto let deviceBlocked = SigninLogs | where TimeGenerated > ago(1d) | where ResultType in ("53001", "53000") | distinct IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where IPAddress in (deviceBlocked) | where ResultType in ("50126", "50053", "53000", "53001", "0") | summarize Users = dcount(UserPrincipalName), Results = make_set(ResultType) by IPAddress | where Users > 1 | sort by Users desc ``` For `AADNonInteractiveUserSignInLogs`, `DeviceDetail` and `LocationDetails` are **string** columns: use `parse_json(DeviceDetail).trustType`. The property names used here follow the Microsoft Graph `signIn` device detail object; check them against one row in your own workspace before building a rule on them. ## How does Conditional Access affect it? - 53001 is produced **by** Conditional Access. The **Conditional Access** tab on the sign-in shows which policy blocked it. - If your fleet is moving to Entra-joined devices, a hybrid-join-only policy will produce 53001 for legitimate corporate devices. Combining "hybrid joined" with "compliant device" as alternatives is the common fix. - As with 53000, pairing the device control with MFA as "require one of" lets a phished MFA result through. Keep a device requirement on its own for admin roles. ## How do I fix AADSTS53001? **For the user:** sign in from your corporate, domain-joined computer. If you are already on one, ask IT to check that its join to Entra ID has completed. **For admins:** 1. Open the sign-in, note the policy and the device. An empty device ID means an unregistered device. 2. If the device is unknown and the IP unfamiliar, treat the password as compromised: reset it, revoke sessions, and check the same IP for other users. 3. If it is a legitimate cloud-joined device, adjust the policy to accept compliant devices too, rather than excluding the user. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Troubleshoot sign-in problems with Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/troubleshoot-conditional-access) 3. [Sign-in log activity details](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-in-log-activity-details) 4. [signIn resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/signin) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS50097](https://brambrinkmeier.com/entra/aadsts/50097/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS135011](https://brambrinkmeier.com/entra/aadsts/135011/), [AADSTS50155](https://brambrinkmeier.com/entra/aadsts/50155/), [AADSTS530003](https://brambrinkmeier.com/entra/aadsts/530003/), [AADSTS530004](https://brambrinkmeier.com/entra/aadsts/530004/), [AADSTS530031](https://brambrinkmeier.com/entra/aadsts/530031/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS53001: Device not domain joined", https://brambrinkmeier.com/entra/aadsts/53001/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/53003/ # AADSTS53003: Access blocked by Conditional Access Canonical: https://brambrinkmeier.com/entra/aadsts/53003/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/53003.json **Short answer:** AADSTS53003 means a Conditional Access policy blocked the sign-in or its grant controls weren't met. The first factor was already accepted, because Conditional Access runs after it. From an unknown IP or country, read it as a valid first factor (password or passwordless) in someone else's hands, stopped by policy. The ConditionalAccessPolicies column names the policy. **Fix:** User: try again from a company device, a supported app or your usual location. Still failing? Give your admin the time and correlation ID. Admin: open the sign-in's Conditional Access tab and find the policy with result Failure. If the source is unfamiliar, reset the password or remove the passkey, and revoke sessions. | Field | Value | |---|---| | Code | AADSTS53003 | | Microsoft name | BlockedByConditionalAccess | | Category | Conditional Access | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-06 | ## What does AADSTS53003 mean? Microsoft's description: > **BlockedByConditionalAccess**: Access has been blocked by Conditional Access policies. The access policy does not allow token issuance. If this is unexpected, see the Conditional Access policy that applied to this request or contact your administrator. The row has `ConditionalAccessStatus` = `failure`. Microsoft defines that as: *"The sign-in satisfied the user and application condition of at least one Conditional Access policy and grant controls are either not satisfied or set to block access."* ## Is it an attack? The key fact is the order of evaluation. Microsoft's Conditional Access overview states: *"Conditional Access policies are enforced after first-factor authentication is completed."* So a 53003 means **the password (or other first factor) was correct**. That's why Microsoft's password spray playbook lists *"53003 - User blocked by Conditional Access"* among the events to review. | Pattern | Likely meaning | |---|---| | A user on a new phone, a personal laptop, or travelling | The policy doing its job on a real user. Benign, possibly a support ticket. | | A block right after a CA policy change, hitting many users | A policy scoped too wide. Configuration, not attack. | | Non-interactive rows for an app that worked yesterday | A token refresh blocked by a new or changed policy. | | 53003 from an IP or country the user has never used, with no matching travel | **A valid first factor in someone else's hands**, stopped by policy (T1078.004). Most often a password, but passwordless sign-in (passkey, Windows Hello, certificate) reaches the same point, so check the authentication method in the sign-in log before you assume a password. Treat that credential as compromised. | | 53003 from an IP that also produced many 50126 across users | The spray found a correct password. CA was the only thing that stopped it. Spray means passwords, so this row does not apply to passwordless users. | | Repeated 53003 for one user from an attacker IP, with changing clients or user agents | Someone with the password is trying to find a client or app your policies don't cover. | ## How do I find it in my logs (KQL)? Which policies are blocking, and for whom. `ConditionalAccessPolicies` is a dynamic array in `SigninLogs`. Expand it and keep the policies whose result is `failure`: ```kusto SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "53003" | mv-expand Policy = ConditionalAccessPolicies | where tostring(Policy.result) == "failure" | project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, ClientAppUsed, PolicyName = tostring(Policy.displayName) | summarize Blocks = count(), Users = dcount(UserPrincipalName), IPs = dcount(IPAddress), Apps = make_set(AppDisplayName, 10) by PolicyName | sort by Blocks desc ``` 53003 from IPs that also sprayed. These users have a known-good password: ```kusto let sprayIPs = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "50126" | summarize FailedUsers = dcount(UserPrincipalName) by IPAddress | where FailedUsers >= 10 | project IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "53003" | where IPAddress in (sprayIPs) | project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, ClientAppUsed, UserAgent | sort by TimeGenerated asc ``` For token refreshes, run the first query against `AADNonInteractiveUserSignInLogs`. There `ConditionalAccessPolicies` is a **string**, so expand `parse_json(ConditionalAccessPolicies)` instead: ```kusto AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "53003" | mv-expand Policy = parse_json(ConditionalAccessPolicies) | where tostring(Policy.result) == "failure" | summarize Blocks = count(), Users = dcount(UserPrincipalName) by PolicyName = tostring(Policy.displayName), AppDisplayName | sort by Blocks desc ``` The `displayName` and `result` field names inside each policy entry follow the Microsoft Graph sign-in object. Run the query once without the `where` filter to see the values your workspace holds. ## How do Conditional Access and MFA affect it? - 53003 **is** Conditional Access. The policy either blocks outright or requires something the sign-in couldn't provide. - Microsoft's troubleshooting guide says the **Conditional Access** tab on the sign-in entry *"shows the specific policy or policies that resulted in the sign-in interruption."* Start there for a single case. - A 53003 with an unexpected source does not mean you are safe. CA stopped this attempt. The attacker still has the credential and can try other apps, clients and locations. ## How do I fix AADSTS53003? **For the user:** the block is deliberate. Try again from a company device, a supported app, or your usual location. If it still fails, give your admin the time of the attempt and the correlation ID from the error page. **For admins:** 1. Open the sign-in entry, go to the **Conditional Access** tab, and find the policy with result Failure. Check which condition matched and which grant control failed. 2. If the block was wrong for a real user, fix the policy scope or help the user meet the control. Don't add a broad exclusion to make one ticket go away. 3. If the source is unfamiliar, treat the credential as compromised: reset the password (or remove the passkey), revoke sessions (`Revoke-MgUserSignInSession`), and look for other sign-ins from the same IP. 4. Look for successful sign-ins from the same IP to apps or clients your policy doesn't cover. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Troubleshoot sign-in problems with Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/troubleshoot-conditional-access) 3. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 4. [Sign-in log activity details](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-in-log-activity-details) 5. [What is Conditional Access? (Microsoft Entra)](https://learn.microsoft.com/en-us/entra/identity/conditional-access/overview) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS53001](https://brambrinkmeier.com/entra/aadsts/53001/), [AADSTS530032](https://brambrinkmeier.com/entra/aadsts/530032/), [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS50053](https://brambrinkmeier.com/entra/aadsts/50053/), [AADSTS50055](https://brambrinkmeier.com/entra/aadsts/50055/), [AADSTS50057](https://brambrinkmeier.com/entra/aadsts/50057/), [AADSTS50072](https://brambrinkmeier.com/entra/aadsts/50072/), [AADSTS50074](https://brambrinkmeier.com/entra/aadsts/50074/), [AADSTS50079](https://brambrinkmeier.com/entra/aadsts/50079/), [AADSTS50097](https://brambrinkmeier.com/entra/aadsts/50097/), [AADSTS50105](https://brambrinkmeier.com/entra/aadsts/50105/), [AADSTS50158](https://brambrinkmeier.com/entra/aadsts/50158/), [AADSTS70043](https://brambrinkmeier.com/entra/aadsts/70043/), [AADSTS70044](https://brambrinkmeier.com/entra/aadsts/70044/), [AADSTS500021](https://brambrinkmeier.com/entra/aadsts/500021/), [AADSTS500121](https://brambrinkmeier.com/entra/aadsts/500121/), [AADSTS530002](https://brambrinkmeier.com/entra/aadsts/530002/), [AADSTS530003](https://brambrinkmeier.com/entra/aadsts/530003/), [AADSTS530004](https://brambrinkmeier.com/entra/aadsts/530004/), [AADSTS530031](https://brambrinkmeier.com/entra/aadsts/530031/), [AADSTS5000211](https://brambrinkmeier.com/entra/aadsts/5000211/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS53003: Access blocked by Conditional Access", https://brambrinkmeier.com/entra/aadsts/53003/ (CC BY 4.0), last updated 2026-11-06. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/54005/ # AADSTS54005: Authorization code already used (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/54005/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/54005.json **Short answer:** AADSTS54005 means an app tried to redeem an OAuth 2.0 authorization code that had already been redeemed. Usually the app sent the same code twice: a double callback, a retry, or a page reload. It is mostly an app bug with low attack value. The app should get a new code, or use the refresh token it already has. **Fix:** Developer: redeem each authorization code once, make the callback handler idempotent, don't retry a redemption after a timeout, and use the refresh token after the first redemption. User: start the sign-in again from the app's start page instead of reloading. | Field | Value | |---|---| | Code | AADSTS54005 | | Category | Tokens and sessions | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS54005 mean? Microsoft's description: > OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token. In the authorization code flow the app gets a `code` at its redirect URI and then sends it to the `/token` endpoint to get tokens. 54005 means a code reached the token endpoint a second time after it had already been exchanged. Microsoft's authorization code flow page says *"Authorization codes are short lived"* and lists the generic token-endpoint error for a bad code: `invalid_grant`, *"The authorization code or PKCE code verifier is invalid or has expired."* Our reading: the app sees `invalid_grant`, and `AADSTS54005` is in the error description and `error_codes`. Microsoft's error reference tells developers to branch on the `error` field and not on the AADSTS number. ## Is it an attack? Usually not. The common causes are in the app: | Pattern | Likely meaning | |---|---| | A success and a 54005 for the same user and app, seconds apart, same IP | The app redeemed the code twice: two callback handlers, a retry after a slow response, or a framework that runs the callback twice. The first call worked. Benign. | | 54005 after the user reloads or uses the back button on the callback page | The page sends the old code again. Benign. | | 54005 for many users of one web app, from your own server's IP | The app's callback code has a bug. Fix the app. | | 54005 from a different IP than the success, for the same user and app | Our interpretation, not documented: someone else got hold of the code and tried it after the real app. The refusal is the protection working, but find out how the code leaked (logs, referrer headers, a shared proxy). | Going by Microsoft's description, the second redemption gets nothing: a code that was already used can't be exchanged for tokens again. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 54005 is logged in. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "54005" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Which apps produce it, and from how many IPs: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "54005" | summarize Rows = count(), Users = dcount(UserPrincipalName), IPs = dcount(IPAddress), SampleIPs = make_set(IPAddress, 5) by AppDisplayName, AppId | sort by Rows desc ``` 54005 from an IP that is different from the one that signed in successfully to the same app shortly before. This is the pattern from the last table row above, which Microsoft doesn't document as an attack signal: ```kusto let window = 10m; let reuse = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "54005" | project ReuseTime = TimeGenerated, UserPrincipalName, AppId, AppDisplayName, ReuseIP = IPAddress; let success = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "0" | project SuccessTime = TimeGenerated, UserPrincipalName, AppId, SuccessIP = IPAddress; reuse | join kind=inner success on UserPrincipalName, AppId | where SuccessTime between ((ReuseTime - window) .. ReuseTime) | where ReuseIP != SuccessIP | summarize Reuses = count(), ReuseIPs = make_set(ReuseIP, 5), SuccessIPs = make_set(SuccessIP, 5) by UserPrincipalName, AppDisplayName | sort by Reuses desc ``` The 10-minute window is a starting point. Expect false positives: a web app redeems the code from its server, so its IP can differ from the browser IP in the user's interactive sign-in. Compare against the app's known server IPs before you treat a hit as suspicious. Non-interactive rows are aggregated when application, user, IP address, status and resource ID match. ## How do I fix AADSTS54005? **For the user:** start the sign-in again from the app's start page, not by reloading the page you landed on. If it keeps happening, report it to whoever runs the app. **For developers:** 1. Redeem each code once. Make the callback handler idempotent: if a second request arrives with the same code, don't send it to `/token` again. 2. Don't retry a code redemption automatically after a timeout. Start a new sign-in instead. 3. After the first redemption, use the refresh token, as Microsoft's description says. The auth code flow page: *"Provide the `refresh_token` instead of the `code`."* Also: *"Refresh tokens aren't revoked when used to acquire new access tokens. You're expected to discard the old refresh token."* 4. Use MSAL instead of hand-written token code; it handles the redemption and cache for you. **For admins:** 1. Use the second query to find the app and hand the time window to its developer. 2. If the third query shows reuse from IPs that aren't the app's servers, treat it as a possible leak of authorization codes and review where codes could be logged or forwarded. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow) 3. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/), [AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS700054](https://brambrinkmeier.com/entra/aadsts/700054/), [AADSTS50196](https://brambrinkmeier.com/entra/aadsts/50196/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS54005: Authorization code already used (fix)", https://brambrinkmeier.com/entra/aadsts/54005/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/65001/ # AADSTS65001: User or admin has not consented to the app Canonical: https://brambrinkmeier.com/entra/aadsts/65001/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/65001.json **Short answer:** AADSTS65001 means an app asked for a token for permissions that no user or admin has consented to. For a new or misconfigured app it is routine. The security angle is consent phishing: watch for an unfamiliar app that flips from 65001 to success, then check the audit log for "Consent to application" and IsAdminConsent. **Fix:** Developer: grant consent for the permissions the app requests (admin consent where needed), then retry the sign-in. Admin: for an app ID you don't recognise, find out who published it and what it asks for before anyone consents. Restrict user consent and enable the admin consent workflow. | Field | Value | |---|---| | Code | AADSTS65001 | | Microsoft name | DelegationDoesNotExist | | Category | Consent and app permissions | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1528](https://attack.mitre.org/techniques/T1528/) Steal Application Access Token, [T1566.002](https://attack.mitre.org/techniques/T1566/002/) Phishing: Spearphishing Link | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs`, `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-25) | | Last updated | 2026-10-30 | ## What does AADSTS65001 mean? Microsoft's description: > **DelegationDoesNotExist**: The user or administrator hasn't consented to use the application with ID X. Send an interactive authorization request for this user and resource. The app asked for a token, but the permission grant it needs doesn't exist. The fix Microsoft names is an interactive request, which is where the consent prompt appears. A sibling: **[65004](https://brambrinkmeier.com/entra/aadsts/65004/) UserDeclinedConsent**, *"User declined to consent to access the app."* That is the user saying no at the prompt. ## Reproduced in the lab On 25 October 2026 an automated lab run sent a token request with the **correct** password for a test user, to a lab app nobody had consented to. The password was right, so the request got past the credential check and stopped at the missing consent. Instead of a token or an MFA prompt, Entra returned `AADSTS65001` with this first line: > AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. That confirms the code and its wording at the token endpoint. The same attempt in the lab tenant's sign-in log (Entra admin center, interactive user sign-ins), with identifiers left out: | Field | Value in the lab row | |---|---| | Status | Interrupted | | Sign-in error code | 65001 | | Application | lab-signin-client | | Authentication requirement | Single-factor authentication | | Conditional Access | Not Applied | | User type | Member | The row is logged as **Interrupted**, not Failure: the password was right and the sign-in waits for consent. A portal view filtered on Status = Failure misses it; filter on the error code instead. The KQL below was run on the lab rows ([how](https://brambrinkmeier.com/methodology/)). Not tested yet: the first query needs a successful sign-in after the consent error and the second needs a consent event in `AuditLogs`, and the exported lab rows have neither. ## Is it an attack? On its own, no. 65001 shows up whenever an app is used before anyone has consented to it, or when a developer adds a new permission and forgets the consent step. The security relevance is **consent phishing** (illicit consent grant). Microsoft describes the attack like this: > the attacker creates a registered application in Microsoft Entra ID that requests access to data such as contact information, email, or documents. The attacker then tricks an end user into granting that application consent … After the illicit application is granted consent, it has account-level access to data without the need for an organizational account. Normal remediation steps (for example, resetting passwords or requiring multifactor authentication (MFA)) aren't effective against this type of attack 65001 is the state the attacker needs to get past. The interesting moment is when it stops. The [consent phishing guide](https://brambrinkmeier.com/guides/investigate-consent-phishing-entra-id/) covers the full investigation and the removal steps. | Pattern | Likely meaning | |---|---| | 65001 for a known, internal app right after a permission change | A developer added a permission and consent wasn't granted yet. Benign. | | 65001 for an app ID you don't recognise, from several users in a short window | Users were sent a link to an app nobody approved. Look at the app and who published it. | | An unfamiliar app goes from 65001 to successful sign-ins | **Someone consented.** Find the consent event in the audit log and check whether it was user or admin consent. | | 65001 for an unknown app in non-interactive or service principal sign-ins | Something is trying to use permissions it was never granted. Identify the app before anyone consents to it. | The table above is reasoning built on Microsoft's attack description, not a list of Microsoft detections. ## How do I find it in my logs (KQL)? Apps that had 65001 and then had successful user sign-ins: ```kusto let window = 7d; let missingConsent = union (SigninLogs | project TimeGenerated, AppId, AppDisplayName, UserPrincipalName, ResultType), (AADNonInteractiveUserSignInLogs | project TimeGenerated, AppId, AppDisplayName, UserPrincipalName, ResultType) | where TimeGenerated > ago(window) | where ResultType == "65001" | summarize FirstMissing = min(TimeGenerated), MissingUsers = dcount(UserPrincipalName) by AppId, AppDisplayName; union (SigninLogs | project TimeGenerated, AppId, UserPrincipalName, ResultType), (AADNonInteractiveUserSignInLogs | project TimeGenerated, AppId, UserPrincipalName, ResultType) | where TimeGenerated > ago(window) | where ResultType == "0" | join kind=inner missingConsent on AppId | where TimeGenerated > FirstMissing | summarize FirstSuccessAfter = min(TimeGenerated), SuccessUsers = dcount(UserPrincipalName) by AppId, AppDisplayName, FirstMissing, MissingUsers | sort by FirstSuccessAfter desc ``` Then find the consent itself. Microsoft's guidance is to search the **Microsoft Purview (unified) audit log** for the activity **"Consent to application"** and check `IsAdminConsent`. The Entra audit log records the same operation; in Log Analytics that is the `AuditLogs` table: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where OperationName == "Consent to application" | extend Actor = tostring(InitiatedBy.user.userPrincipalName), AppName = tostring(TargetResources[0].displayName), AppObjectId = tostring(TargetResources[0].id), ConsentDetails = TargetResources[0].modifiedProperties | project TimeGenerated, Actor, AppName, AppObjectId, Result, ConsentDetails | sort by TimeGenerated desc ``` `ConsentDetails` holds the modified properties of the grant, which is where the admin-consent flag and the granted permissions appear. In the Entra audit log those are the properties named `ConsentContext.IsAdminConsent` and `ConsentAction.Permissions`, not a top-level `IsAdminConsent` field as in Purview. The exact field paths inside `InitiatedBy` and `TargetResources` vary; check them against a real event in your workspace before you build an alert on them. `ResultType` is a **string** column, so compare it with `"65001"`, not `65001`. ## How do Conditional Access and MFA affect it? - 65001 isn't caused by Conditional Access. It is a missing permission grant. - MFA does not protect against consent phishing. In Microsoft's words, resetting passwords or requiring MFA *"aren't effective against this type of attack"*, because the app keeps its own access after consent. - The control that matters is who may consent. Restrict user consent and turn on the admin consent workflow, so a user who hits a consent prompt for a risky app gets [90095](https://brambrinkmeier.com/entra/aadsts/90095/) and a request goes to a reviewer, instead of granting access themselves. ## How do I fix AADSTS65001? **For developers:** grant consent for the permissions the app requests (admin consent for permissions that need it), then retry the sign-in. **For admins:** 1. For an app ID you don't recognise, find out who published it and what it asks for **before** anyone consents. 2. If an unknown app flipped from 65001 to success, find the "Consent to application" event, check whether it was admin consent, and review what the app accessed. 3. Remove consent from and disable any app you confirm as malicious. Resetting the user's password alone does not cut off its access. 4. Restrict user consent and enable the admin consent workflow as your standing posture. ## Evidence Reproduced in a lab tenant on 2026-10-25 (ROPC token request against a lab tenant; scenario: Correct password (security defaults / MFA / consent decide)). First line returned: > AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Sign-in log row read: 2026-10-30. Lab-run rows naming this code (16; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | SPA-registered client redeems without an Origin header | 9002327 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-spa-41136574530'. Send | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | SPA-registered client redeems without an Origin header | 9002327 / 65001 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-spa-41139925607'. Send | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-30 | SPA-registered client redeems without an Origin header | 9002327 / 65001 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-spa-41143330001'. Send | | 2026-10-30 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-31 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-31 | SPA-registered client redeems without an Origin header | 9002327 / 65001 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-spa-41146039117'. Send | | 2026-10-31 | Correct password (security defaults / MFA / consent decide) | success / 50076 / 50079 / 65001 / 50072 | success | | | 2026-10-31 | SPA-registered client redeems without an Origin header | 9002327 / 65001 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-spa-41150019626'. Send | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Detect and remediate illicit consent grants](https://learn.microsoft.com/en-us/defender-office-365/detect-and-remediate-illicit-consent-grants) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS90094](https://brambrinkmeier.com/entra/aadsts/90094/), [AADSTS90095](https://brambrinkmeier.com/entra/aadsts/90095/), [AADSTS65004](https://brambrinkmeier.com/entra/aadsts/65004/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), [AADSTS50013](https://brambrinkmeier.com/entra/aadsts/50013/), [AADSTS50105](https://brambrinkmeier.com/entra/aadsts/50105/), [AADSTS65002](https://brambrinkmeier.com/entra/aadsts/65002/), [AADSTS65005](https://brambrinkmeier.com/entra/aadsts/65005/), [AADSTS90009](https://brambrinkmeier.com/entra/aadsts/90009/), [AADSTS500341](https://brambrinkmeier.com/entra/aadsts/500341/), [AADSTS501051](https://brambrinkmeier.com/entra/aadsts/501051/), [AADSTS650052](https://brambrinkmeier.com/entra/aadsts/650052/), [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/), [AADSTS1003031](https://brambrinkmeier.com/entra/aadsts/1003031/), [AADSTS7000112](https://brambrinkmeier.com/entra/aadsts/7000112/), [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS9002341](https://brambrinkmeier.com/entra/aadsts/9002341/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS65001: User or admin has not consented to the app", https://brambrinkmeier.com/entra/aadsts/65001/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/65002/ # AADSTS65002 fix: Microsoft app not preauthorized for API Canonical: https://brambrinkmeier.com/entra/aadsts/65002/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/65002.json **Short answer:** AADSTS65002 means a Microsoft-owned client app asked for a token for a Microsoft-owned API it isn't preauthorized for. Nobody in your tenant can grant that consent. Users hit it from Visual Studio sign-in in the Azure SDK, from scripts that borrow a Microsoft client ID, and from an old Azure Virtual Desktop web client URL. Use your own app registration or the current client. **Fix:** Developer: stop using a Microsoft-owned client ID. Register your own app, add the API permissions it needs, and use that client ID. Azure SDK with Visual Studio sign-in: use another credential or your own app. Azure Virtual Desktop user: open the current web client, not the old rdweb URL. | Field | Value | |---|---| | Code | AADSTS65002 | | Category | Consent and app permissions | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS65002 mean? Microsoft's description: > Consent between first party application '{applicationId}' and first party resource '{resourceId}' must be configured via preauthorization - applications owned and operated by Microsoft must get approval from the API owner before requesting tokens for that API. A developer in your tenant might be attempting to reuse an App ID owned by Microsoft. This error prevents them from impersonating a Microsoft application to call other APIs. They must move to another app ID they register. Both sides of the request are Microsoft apps ("first party"). The client app isn't on the API's preauthorized list, so Entra ID refuses the token. The error names both app IDs, so you can see exactly which pair failed. The difference from [65001](https://brambrinkmeier.com/entra/aadsts/65001/): with 65001 a user or admin in your tenant can grant the missing consent. With 65002 nobody in your tenant can. Microsoft's text says the approval comes from *"the API owner"*, which is Microsoft. A Microsoft moderator's accepted answer in a Q&A thread about Azure Virtual Desktop single sign-on puts it similarly: *"This type of consent is not intended to be granted manually by end users or tenant admins and must be handled via internal preauthorization within Microsoft's platform."* ## Is it an attack? Usually not. Users report three situations: | Pattern | Likely meaning | |---|---| | Client `{guid}`, from a developer machine | Visual Studio sign-in through the Azure SDK (`VisualStudioCredential`). Microsoft's Azure SDK troubleshooting guide lists this exact error and says the Visual Studio client *"is not yet pre-authorized for the Azure resource mentioned in the error."* | | A script or integration that sends a Microsoft-owned client ID | A developer copied a Microsoft client ID into their own code. This is the case Microsoft's description warns about. The row rests on Microsoft's description. One Q&A thread is sometimes read as this case, but the poster was using their own client ID and the thread was never resolved, so it doesn't show it. | | Client `9cdead84-a844-4324-93f2-b2e6bb768d07` (Azure Virtual Desktop) for resource `00000002-0000-0000-c000-000000000000` | An Azure Virtual Desktop user on an old web client URL. The app names come from the poster's Enterprise applications list. The poster fixed it by switching to the current web client. | | One user or IP hitting 65002 for several **different** Microsoft client IDs in a short time | Our interpretation, not documented: someone is trying Microsoft client IDs one after another to find one that gets a token. Microsoft's text calls 65002 a guard against *"impersonating a Microsoft application"*. Check who and where. | The error itself gives nothing away: no token is issued. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 65002 lands in. Check all three: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "65002" | summarize Rows = count(), Clients = dcount(AppId) by SourceTable ``` Which client and resource pairs fail, and from what. Microsoft's page on verifying first-party apps gives two Microsoft owner tenants: `f8cdef31-a31e-4b4a-93e4-5f571e91255a` (*"the Microsoft Service's Microsoft Entra tenant ID"*) and `72f988bf-86f1-41af-91ab-2d7cd011db47`, under which its table lists Microsoft-owned apps. The `IsMicrosoftClient` column checks both: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "65002" | extend IsMicrosoftClient = AppOwnerTenantId in ("f8cdef31-a31e-4b4a-93e4-5f571e91255a", "72f988bf-86f1-41af-91ab-2d7cd011db47") | summarize Rows = count(), Users = dcount(UserPrincipalName), UserAgents = make_set(UserAgent, 5), IPs = make_set(IPAddress, 5) by AppDisplayName, AppId, IsMicrosoftClient, ResourceDisplayName, ResourceIdentity | sort by Rows desc ``` One user or IP trying several different client IDs and getting 65002. A threshold of 3 client IDs in an hour is a starting point; raise it if your developers trigger it: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "65002" | summarize ClientIds = dcount(AppId), Clients = make_set(AppDisplayName, 10), Resources = make_set(ResourceDisplayName, 10) by UserPrincipalName, IPAddress, bin(TimeGenerated, 1h) | where ClientIds >= 3 | sort by ClientIds desc ``` `ResultType` is a **string** column, so compare it with `"65002"`, not `65002`. If an app in the results is unfamiliar, Microsoft's guide to verifying first-party apps shows how to check its owner: in **Enterprise applications**, filter **Application Type** to **Microsoft Applications**. First-party apps don't always have a service principal in your tenant, so they can appear in sign-in logs without appearing there. ## How do I fix AADSTS65002? **For the user:** you can't fix this with consent, and neither can your admin. Report the error with both app IDs to whoever runs the app. On Azure Virtual Desktop, a user fixed it by using `https://client.wvd.microsoft.com/arm/webclient` instead of the old `https://rdweb.wvd.microsoft.com/` address. **For developers:** 1. Look at the client ID your code actually sends. If it belongs to Microsoft, Microsoft's instruction is plain: *"They must move to another app ID they register."* 2. Register your own app, add the API permissions it needs under **API permissions**, and get them consented. Then send that client ID. 3. Azure SDK with `VisualStudioCredential`: the Azure SDK guide points to Visual Studio's pre-authorization guidance. The reporter in the GitHub issue said that didn't help for Azure Monitor Control Service. Our reading: switch to a different credential, or your own app registration, for that resource. **For admins:** 1. Use the second query to find the client, the resource and the user agent. That tells you whether it is a developer tool, a script or an end-user client. 2. Don't look for a consent button. There isn't one for this error. 3. If the third query returns hits from an unfamiliar IP, treat it like any other suspicious sign-in for that user. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Verify first-party Microsoft applications in sign-in reports](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 4. [Azure Identity client library for .NET troubleshooting guide (Microsoft, GitHub)](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/TROUBLESHOOTING.md) 5. [VisualStudioCredential error AADSTS65002 connecting to Azure Monitor Control Service (GitHub issue)](https://github.com/Azure/azure-sdk-for-net/issues/44107) 6. [401 / AADSTS65002 when trying to authenticate with api.partner.microsoft.com (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/962674/401-aadsts65002-when-trying-to-authenticate-with-a) 7. [AVD setup configured with SSO errors at the consent (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/2282577/avd-setup-configured-with-sso-errors-at-the-consen) ## Related codes [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS90094](https://brambrinkmeier.com/entra/aadsts/90094/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS65002 fix: Microsoft app not preauthorized for API", https://brambrinkmeier.com/entra/aadsts/65002/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/65004/ # AADSTS65004: User declined to consent to access the app Canonical: https://brambrinkmeier.com/entra/aadsts/65004/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/65004.json **Short answer:** AADSTS65004 means the app asked for consent and the user did not give it. Microsoft also documents it as an expected part of the admin consent workflow: after a user submits a request and selects Back to app, the app receives 65004. It has low attack value on its own. Check the app if one unfamiliar app collects declines from many users. **Fix:** User: if you just sent an admin consent request, wait for approval, then sign in again. If you cancelled by mistake and trust the app, sign in again and accept. Admin: check for a 90095 from the same user and app and review the pending request, or grant admin consent to an approved app. | Field | Value | |---|---| | Code | AADSTS65004 | | Microsoft name | UserDeclinedConsent | | Category | Consent and app permissions | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-25 | ## What does AADSTS65004 mean? Microsoft's description: > **UserDeclinedConsent**: User declined to consent to access the app. Have the user retry the sign-in and consent to the app The app sent the user to a consent prompt and came back without a grant. In the OAuth authorization code flow, Microsoft lists the matching protocol error as `access_denied`, *"Resource owner denied consent"*, and says *"The client application can notify the user that it can't continue unless the user consents."* ## What is the quick fix? First work out which of two cases you are in: - **The user just submitted an admin consent request.** Microsoft documents this as expected: *"After a user submits an admin consent approval for an application, another dialog appears with a **Back to app** button. When the user selects the button, Microsoft Entra ID sends an AADSTS65004 error to the redirect URI specified in the original authentication request. This error is an expected part of the admin consent workflow."* Wait for the reviewer. After approval, *"the user needs to begin a new authentication process with the application."* - **The user said no at the prompt.** If the app is one you trust, have the user sign in again and accept, as Microsoft's description says. If the user can't accept because the permissions need an admin, that is a different code: [90094](https://brambrinkmeier.com/entra/aadsts/90094/), or [90095](https://brambrinkmeier.com/entra/aadsts/90095/) with the admin consent workflow on. ## Is it an attack? No, not on its own. 65004 is the absence of a grant. The risky moment in consent phishing is a grant that does happen. Microsoft describes the attack: the attacker *"tricks an end user into granting that application consent"*, and after that the app *"has account-level access to data without the need for an organizational account."* The [consent phishing guide](https://brambrinkmeier.com/guides/investigate-consent-phishing-entra-id/) covers that investigation. | Pattern | Likely meaning | |---|---| | 65004 shortly after [90095](https://brambrinkmeier.com/entra/aadsts/90095/) for the same user and app | The admin consent workflow as documented. Benign. | | 65004 for a known app, then a success after the user retried | The user cancelled once, then accepted. Benign. | | 65004 for an app ID you don't recognise, from several users | Users were sent to an app nobody approved, and some said no. Check whether others said yes. | The second and third rows are reasoning from what the code means, not Microsoft detections. ## How do I find it in my logs (KQL)? 65004 per app, with how many of those users also hit 90095 (the admin consent workflow) for the same app: ```kusto let window = 7d; let declines = SigninLogs | where TimeGenerated > ago(window) | where ResultType == "65004" | project DeclineTime = TimeGenerated, UserPrincipalName, AppId, AppDisplayName, IPAddress; let requests = SigninLogs | where TimeGenerated > ago(window) | where ResultType == "90095" | distinct UserPrincipalName, AppId | extend RequestedAdminConsent = true; declines | join kind=leftouter requests on UserPrincipalName, AppId | summarize Declines = count(), Users = dcount(UserPrincipalName), UsersWithAdminRequest = dcountif(UserPrincipalName, RequestedAdminConsent == true), FirstSeen = min(DeclineTime) by AppId, AppDisplayName | sort by Users desc ``` Apps where `Users` is much larger than `UsersWithAdminRequest` are the ones where people said no at the prompt. For an app you don't know, check the [65001 page](https://brambrinkmeier.com/entra/aadsts/65001/) query to see whether anyone later consented. `ResultType` is a **string** column, so compare it with `"65004"`, not `65004`. ## How do Conditional Access and consent settings affect it? - 65004 isn't caused by Conditional Access. It is a consent decision. - With user consent restricted, a user who can't grant the permissions gets [90094](https://brambrinkmeier.com/entra/aadsts/90094/). With the admin consent workflow on, they get [90095](https://brambrinkmeier.com/entra/aadsts/90095/), can send a request, and the Back to app step then returns 65004. - Microsoft notes that users can't grant consent to apps Microsoft detects as risky. Admins can, but Microsoft says they *"should evaluate the app carefully and proceed with caution."* ## How do I fix AADSTS65004? **For the user:** if you just sent an admin consent request, wait for approval and then sign in to the app again. If you cancelled by mistake and trust the app, sign in again and accept. **For developers:** handle `access_denied` by telling the user the app can't continue without consent, as Microsoft recommends. **For admins:** 1. Check whether the 65004 followed a 90095 for the same user and app. If yes, review the pending request. 2. If the app is approved for the organization, grant admin consent so users don't see the prompt. 3. For an app you don't recognise, find who published it and what it asks for before anyone consents. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Unexpected error when performing consent to an application](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/application-sign-in-unexpected-user-consent-error) 3. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow) 4. [Detect and remediate illicit consent grants](https://learn.microsoft.com/en-us/defender-office-365/detect-and-remediate-illicit-consent-grants) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS90095](https://brambrinkmeier.com/entra/aadsts/90095/), [AADSTS90094](https://brambrinkmeier.com/entra/aadsts/90094/), [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS65004: User declined to consent to access the app", https://brambrinkmeier.com/entra/aadsts/65004/ (CC BY 4.0), last updated 2026-10-25. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/65005/ # AADSTS65005 fix: app asks for a resource it didn't register Canonical: https://brambrinkmeier.com/entra/aadsts/65005/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/65005.json **Short answer:** AADSTS65005 means an app asked for access to a resource (an API) that isn't in the app's registered permissions, or that isn't available in the tenant. For SAML apps it can also mean a wrong Identifier (Entity ID). Users hit it on company apps, scripts and integrations that sign in to Microsoft 365, Intune or Dynamics. It is a configuration error with low attack value. **Fix:** Developer: add the resource and every permission your code requests under App registrations > API permissions. Admin: if the resource isn't in your tenant, provision it by subscription, consent, admin center grant or gallery. SAML app: match the Identifier (Entity ID). | Field | Value | |---|---| | Code | AADSTS65005 | | Microsoft name | MisconfiguredApplication | | Category | Consent and app permissions | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS65005 mean? Microsoft's description: > **MisconfiguredApplication**: The app required resource access list doesn't contain apps discoverable by the resource, or the client app has requested access to resource, which wasn't specified in its required resource access list or Graph service returned bad request or resource not found. If the app supports SAML, you might have configured the app with the wrong Identifier (Entity). To learn more, see the troubleshooting article for error AADSTS650056. The "required resource access list" is the list of APIs and permissions in the app's registration (**API permissions** in the portal, `requiredResourceAccess` in the manifest). An older Microsoft KB quotes the message users saw: *"The client application has requested access to resource. This request has failed because the client has not specified this resource in its requiredResourceAccess list."* Microsoft's consent troubleshooting article shows two other wordings, which point at two different causes: - **Resource not available in the tenant**: *"`clientAppDisplayName` is requesting access to a resource `resourceAppDisplayName` that isn't available in your organization."* - **Permissions mismatch**: *"The app requested consent to access resource `resourceAppDisplayName`. This request failed because it doesn't match how the app was preconfigured during app registration."* How it differs from codes that already have pages: - [650056](https://brambrinkmeier.com/entra/aadsts/650056/) is also "misconfigured application", with missing permissions, missing admin consent or a wrong identifier. The two overlap, and Microsoft's 65005 description sends SAML cases to the 650056 article. Our reading: start with the resource named in the 65005 message. - [500011](https://brambrinkmeier.com/entra/aadsts/500011/) means the resource has no service principal in the tenant at token time. 65005 can have the same root cause, a missing resource service principal. Our reading is that it tends to show up at consent rather than at token time. ## Is it an attack? No. The request fails because the app is set up wrong, and nothing is granted. Users report it in a few typical places: - Microsoft's KB: *"When you use a company app to sign in to or authenticate to one of the Microsoft Cloud Services, such as Microsoft 365, Microsoft Intune, Microsoft Dynamics, Microsoft Power BI, or Microsoft Azure."* The KB's cause: the app *"may not be registered with Microsoft Entra ID, or it may not have the correct permissions applied."* - A Linux PAM module for Entra ID sign-in (pam_aad): the author found the app's permissions were set on the legacy Windows Azure Active Directory API instead of Microsoft Graph. | Pattern | Likely meaning | |---|---| | One in-house app or script, every user, after a code change | The code asks for an API that isn't in the registration. Developer error. | | A vendor app fails at the consent screen in your tenant only | The API it needs isn't provisioned in your tenant. Setup step missing. | | A SAML app fails for everyone | Wrong Identifier (Entity ID). Follow the [650056](https://brambrinkmeier.com/entra/aadsts/650056/) fix. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 65005 lands in. Check your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "65005" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which client apps fail, and which resources they asked for: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "65005" | summarize Rows = count(), Users = dcount(UserPrincipalName), Resources = make_set(ResourceDisplayName, 10), Protocols = make_set(AuthenticationProtocol, 5), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppDisplayName, AppId | sort by Users desc ``` The resource in the request may not exist in your tenant, so `ResourceDisplayName` can be empty on these rows. Microsoft doesn't document it either way. If it is empty, read the resource name from the error message the user saw. Failed consent attempts in the audit log. Microsoft lists **Consent to application** as an `ApplicationManagement` activity. Our assumption: a consent stopped by 65005 is logged there as a failure. ```kusto AuditLogs | where TimeGenerated > ago(30d) | where Category == "ApplicationManagement" | where OperationName == "Consent to application" | where Result =~ "failure" | project TimeGenerated, App = tostring(TargetResources[0].displayName), ByUser = tostring(InitiatedBy.user.userPrincipalName), ResultReason | sort by TimeGenerated desc ``` `ResultType` is a **string** column, so compare it with `"65005"`. ## How do I fix AADSTS65005? **For the user:** you can't fix this. Send IT the app name and the resource named in the error. **For developers (you own the app registration):** 1. Open **App registrations** > your app > **API permissions**. Add every API and permission your code requests. Microsoft: *"Compare the resource you're requesting access to in code with the configured permissions in the **Required Resources** tab to make sure you only request resources you've configured."* 2. Check you registered the right API. In the pam_aad report, permissions were on the legacy Windows Azure Active Directory API while the code needed Microsoft Graph. 3. Microsoft's consent article: when the app requests an invalid resource, *"the application developer must update the configuration of the client application to resolve this problem."* **For admins:** 1. If the resource isn't in your tenant, provision its service principal. Microsoft lists four ways, depending on the app: *"Acquiring a subscription for the resource application (Microsoft-published applications)"*, *"Consenting to the resource application"*, *"Granting the application permissions via the Microsoft Entra admin center"*, and *"Adding the application from the Microsoft Entra application gallery."* 2. For a vendor app you don't own, the fix is on the vendor's side if its registration requests the wrong resource. Microsoft's message says *"Contact the app vendor."* 3. For a SAML app, check that the **Identifier (Entity ID)** in Entra ID matches the Issuer the app sends. See [650056](https://brambrinkmeier.com/entra/aadsts/650056/). ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Unexpected error when performing consent to an application](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/application-sign-in-unexpected-user-consent-error) 3. [AADSTS65005 error when you try to sign in to Microsoft Cloud services](https://learn.microsoft.com/microsoft-365/troubleshoot/active-directory/aadsts65005-error-when-sign-in-cloud) 4. [Problems signing in to SAML-based single sign-on configured apps](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/troubleshoot-sign-in-saml-based-apps) 5. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) 6. [AADSTS65005: Misconfigured application (pam_aad GitHub issue, user report)](https://github.com/cyberninjas/pam_aad/issues/6) ## Related codes [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS50001](https://brambrinkmeier.com/entra/aadsts/50001/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS65005 fix: app asks for a resource it didn't register", https://brambrinkmeier.com/entra/aadsts/65005/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/70002/ # AADSTS70002 fix: error validating client credentials Canonical: https://brambrinkmeier.com/entra/aadsts/70002/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/70002.json **Short answer:** AADSTS70002 means Microsoft Entra ID couldn't validate the credentials an app sent, typically a client secret that doesn't match. A wrong secret today often comes back as 7000215 instead. 70002 is also seen as an outer code in front of a more specific one, so read the whole message. Usually a setup mistake; repeated failures from IPs you don't own deserve a look. **Fix:** Developer: read the second AADSTS code in the message, then send the secret's Value (not its ID) for the right app and tenant, or create a new secret. Admin: after a rotation, update every system that still fails. If failures come from IPs you don't own, replace the app's credentials. | Field | Value | |---|---| | Code | AADSTS70002 | | Microsoft name | InvalidClient | | Category | App configuration | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS70002 mean? Microsoft's description: > **InvalidClient**: Error validating the credentials. The specified client_secret does not match the expected value for this client. Correct the client_secret and try again. For more info, see [Use the authorization code to request an access token](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow#redeem-a-code-for-an-access-token). A confidential client, such as a web app, a daemon or a connector, proves who it is with a client secret or a certificate. Microsoft's authorization code flow reference says the `client_secret` is *"the application secret that you created in the app registration portal for your app"* and that it *"must be URL-encoded before being sent"*. The SDK does that for you; a hand-built request may not. When Entra can't validate what was sent, the token request fails. ### 70002 or 7000215? Both are about a bad client secret, and they are easy to confuse. - [7000215](https://brambrinkmeier.com/entra/aadsts/7000215/) is *"Invalid client secret is provided"*. Its page records a token request with a wrong secret that came back as 7000215, with Microsoft's current hint to send *"the client secret value, not the client secret ID"*. A Microsoft Q&A thread that people find when searching for 70002, a Postman call with the wrong secret, also shows 7000215. - 70002 still appears in user reports, often with a second code after it. Quest's knowledge base shows *"AADSTS70002: Error validating credentials. AADSTS50126: Invalid username or password"*. Microsoft's own external MFA provider reference shows *"AADSTS70002: Error validating credentials. AADSTS50012: External ID token from issuer ... failed signature verification"* (Microsoft prints the prefix there as `ENTRA IDSTS`). Our reading: 70002 works as a general "credential check failed" code, and the code that follows it says what actually failed. If your message has a second AADSTS code, look that one up: [50126](https://brambrinkmeier.com/entra/aadsts/50126/) is a wrong user password, and 50012 is a token whose signature didn't verify. If 70002 stands alone, treat it as a wrong client secret. Other neighbours: - [7000222](https://brambrinkmeier.com/entra/aadsts/7000222/): the secret was right but has expired. - [7000218](https://brambrinkmeier.com/entra/aadsts/7000218/): no secret or assertion was sent at all. - [700016](https://brambrinkmeier.com/entra/aadsts/700016/): the client ID isn't found in the tenant. Check this first if the secret is definitely right. ## Is it an attack? Usually not. The causes users report are setup mistakes: the secret ID pasted instead of the value, an old secret left in a config file after a rotation, or the right secret for the wrong app or tenant. UiPath's documentation, for example, tells users to check the tenant ID and application ID and to *"copy the Secret Value, not the Secret ID"*. | Pattern | Likely meaning | |---|---| | Failures for one app from your own servers, starting at a rotation date | A system still has the old secret. Update it. | | Failures since day one of a new integration | Secret ID instead of value, or a secret for another app registration. | | 70002 followed by 50126 | A user's password was wrong. See [50126](https://brambrinkmeier.com/entra/aadsts/50126/), not this page. | | Repeated failures for one app from IPs you don't own | Someone has an old or leaked secret, or is guessing. Treat it like [7000215](https://brambrinkmeier.com/entra/aadsts/7000215/) from a foreign IP (T1078.004 if it ever succeeds). | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 70002 lands in. App-only requests would be expected in `AADServicePrincipalSignInLogs`, and requests on behalf of a user in the user tables; that is an assumption. Check, and compare with 7000215 so you see which code your tenant actually returns. One caveat, as on the [7000215 page](https://brambrinkmeier.com/entra/aadsts/7000215/): the reference for `AADServicePrincipalSignInLogs` describes `ResultType` as *"Success or Failure"*, so confirm failed rows carry the code; if they don't, filter on `ResultSignature` instead: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType in ("70002", "7000215") | summarize Rows = count() by SourceTable, ResultType ``` Which apps fail, from where, and with which key. Microsoft documents `ClientCredentialType` as the type of client credential used (for example client assertion or client secret) and `ServicePrincipalCredentialKeyId` as the key ID of the credential: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType in ("70002", "7000215") | summarize Attempts = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), CredTypes = make_set(ClientCredentialType, 5), KeyIds = make_set(ServicePrincipalCredentialKeyId, 10) by AppId, ServicePrincipalName, IPAddress, ResultType | sort by Attempts desc ``` Failures from IPs that have never signed in successfully for that app in the last 30 days. Worth an alert; the 30-day window and a threshold of one are starting points: ```kusto let knownAppIPs = AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "0" | distinct AppId, IPAddress; AADServicePrincipalSignInLogs | where TimeGenerated > ago(1d) | where ResultType in ("70002", "7000215") | join kind=leftanti knownAppIPs on AppId, IPAddress | summarize Attempts = count(), LastSeen = max(TimeGenerated) by AppId, ServicePrincipalName, IPAddress, ResultType | sort by Attempts desc ``` If the first query shows 70002 only in the user tables, run the third one against those with `UserPrincipalName` added. `ResultType` is a **string** column, so compare it with `"70002"`, not `70002`. ## How do I fix AADSTS70002? **For developers:** 1. Read the full message. If a second AADSTS code follows, fix that one. 2. Send the secret's **Value**, not its ID, for the same app registration as the `client_id`, against the tenant that app lives in. 3. If you build the request by hand, URL-encode the secret, as Microsoft's reference requires. 4. If you can't find the value any more, create a new client secret and use that. **For admins:** 1. After a rotation, use the second query to find every system still failing, and update it. 2. If failures come from IPs you don't own, treat the app's secrets as exposed: create a new credential, remove the old ones from the app registration, and update your own systems. 3. Move the app to a certificate where it supports one. Microsoft *"recommends that you use a certificate instead of a client secret before moving the application to a production environment."* ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. Lab-run rows naming this code (2; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-31 | Device code redeemed with a different client ID | 70016 / 7000215 / 70002 | 90023 | AADSTS90023: ClientId passed in the request doesn't match the one in cache | | 2026-10-31 | Device code redeemed with a different client ID | 70016 / 7000215 / 70002 | 90023 | AADSTS90023: ClientId passed in the request doesn't match the one in cache | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow) 3. [Microsoft Entra multifactor authentication external method provider reference](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-external-method-provider) 4. [Add credentials to your application](https://learn.microsoft.com/en-us/entra/identity-platform/how-to-add-credentials) 5. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) 6. [Microsoft Q&A: Problem using Postman to call REST APIs](https://learn.microsoft.com/en-us/answers/questions/323082/problem-using-postman-to-call-rest-apis-error-desc) 7. [UiPath documentation: AADSTS70002 Error validating credentials](https://docs.uipath.com/activities/other/latest/productivity/aadsts70002-error-validating-credentials.md) 8. [Quest knowledge base: AADSTS70002 Error validating credentials. AADSTS50126](https://support.quest.com/kb/4258624/aadsts70002-error-validating-credentials-aadsts50126-invalid-username-or-password) ## Related codes [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS7000222](https://brambrinkmeier.com/entra/aadsts/7000222/), [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS70002 fix: error validating client credentials", https://brambrinkmeier.com/entra/aadsts/70002/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/70008/ # AADSTS70008: The refresh token has expired or was revoked (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/70008/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/70008.json **Short answer:** AADSTS70008 means an app tried to use a refresh token or grant that is no longer valid. Microsoft's text names inactivity; the code name also says revoked. It is usually part of the normal token lifecycle and has low attack value. The app should send the user to an interactive sign-in. Hunt it in the non-interactive sign-in logs. **Fix:** User: sign in again when the app asks; if it keeps failing without asking, sign out of the app and back in. Developer: treat 70008 as interactive sign-in needed and fall back from the silent call to an interactive one. Don't retry the same refresh token. | Field | Value | |---|---| | Code | AADSTS70008 | | Microsoft name | ExpiredOrRevokedGrant | | Category | Tokens and sessions | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `AADNonInteractiveUserSignInLogs`, `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS70008 mean? Microsoft's description: > **ExpiredOrRevokedGrant**: The refresh token has expired due to inactivity. The token was issued on XXX and was inactive for a certain amount of time. An app presented a refresh token (a "grant") to get a new access token, and Microsoft Entra ID refused it. The description talks about inactivity. The code name, *ExpiredOrRevokedGrant*, also covers revocation. Microsoft doesn't say which cases return 70008 rather than a more specific code. Two sibling codes in the same reference table are more specific: - [700082](https://brambrinkmeier.com/entra/aadsts/700082/) **ExpiredOrRevokedGrantInactiveToken**, with almost the same text, which Microsoft calls an *"Expected part of the token lifecycle"*. - [50173](https://brambrinkmeier.com/entra/aadsts/50173/), a grant revoked after a credential change: *"The user might have changed or reset their password."* Our reading: 70008 is the more generic form of the same event. Treat it like 700082 unless the context points to revocation. **How long refresh tokens live.** Microsoft's refresh token page gives the defaults: *"24 hours for single-page applications"*, 24 hours for the email one-time passcode flow, and *"90 days for all other scenarios."* The configurable token lifetimes page lists a non-configurable *Refresh Token Max Inactive Time* of 90 days. Tokens *"can be revoked by the sign-in service at any time before their expiration"*, for example when the user changes their password or an admin revokes all refresh tokens for the user. ## Is it an attack? Usually not. A refresh token that expired or was revoked gives nobody access. The common sources are a device or app that wasn't used for a long time, and an app that keeps an old token after a password change or a session revocation. | Pattern | Likely meaning | |---|---| | 70008 from a user's known device, then an interactive success | The user came back after a long break, or after a password change, and signed in again. Benign. | | 70008 for many users of one app, all at once | Our interpretation: a mass revocation (for example after an incident response) or an app holding tokens far past their lifetime. Check what happened that day. | | 70008 shortly after you revoked a user's sessions | The revocation is working. The old token was refused. | | 70008 from an IP or device the user doesn't normally use | Someone presented an old refresh token from an unfamiliar place. Reasoning, not a documented detection: if the token was stolen, expiry or revocation is what stopped it. Worth a short look. | **IP caveat.** Microsoft's non-interactive sign-ins page says the IP of non-interactive sign-ins by confidential clients *"doesn't match the actual source IP of where the refresh token request is coming from. Instead, it shows the original IP used for the original token issuance."* An unfamiliar IP on a 70008 row is a meaningful signal mainly for public clients (desktop, mobile and browser apps). ## How do I find it in my logs (KQL)? Refresh token redemption is a non-interactive sign-in (*"A client app uses an OAuth 2.0 refresh token to get an access token"* is one of Microsoft's examples), so expect most rows in `AADNonInteractiveUserSignInLogs`. Microsoft doesn't document the table for this code specifically, so check: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "70008" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Baseline by app and client: ```kusto AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "70008" | summarize Rows = count(), Users = dcount(UserPrincipalName) by AppDisplayName, ClientAppUsed | sort by Rows desc ``` 70008 from an IP the user had no successful sign-in from in the previous 13 days (14 days back up to yesterday). Use it for triage, not as an alert on its own, and keep the confidential-client caveat above in mind: ```kusto let lookback = 14d; let knownIPs = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated between (ago(lookback) .. ago(1d)) | where ResultType == "0" | distinct UserPrincipalName, IPAddress; AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "70008" | join kind=leftanti knownIPs on UserPrincipalName, IPAddress | summarize Rows = count(), Apps = make_set(AppDisplayName, 5), UserAgents = make_set(UserAgent, 3) by UserPrincipalName, IPAddress | sort by Rows desc ``` Non-interactive rows are aggregated when application, user, IP address, status and resource ID match, so `Rows` is not a request count. `ResultType` is a **string** column, so compare it with `"70008"`, not `70008`. ## How does Conditional Access affect it? - Refresh token lifetimes can't be changed with policy. Microsoft says that *"As of January 30, 2021, refresh and session token lifetimes are no longer configurable through token lifetime policies."* - To control how often users sign in, Microsoft points to Conditional Access sign-in frequency. A refresh refused because of sign-in frequency is a different code, [70043](https://brambrinkmeier.com/entra/aadsts/70043/). ## How do I fix AADSTS70008? **For the user:** sign in again when the app asks. If the app keeps failing without asking, sign out of it and back in. **For developers:** treat 70008 as *"interactive sign-in needed"*. Microsoft's guidance for refresh tokens is that the app *"should handle such revocations gracefully by redirecting the user to an interactive sign-in prompt"*. With MSAL, catch the error from the silent call and fall back to an interactive call. Don't retry the same refresh token. For single-page apps, plan for the 24-hour limit: Microsoft says they *"must be prepared to rerun the authorization code flow using an interactive authentication"*. **For admins:** 1. Nothing is broken in the normal case. Exclude `"70008"` from failure-rate dashboards. 2. If one app produces most of the rows and users complain, the app probably doesn't fall back to an interactive sign-in. Report it to the developer. 3. If the third query shows rows from unfamiliar public-client IPs, check that user's other sign-ins from the same IP. If anything succeeded there, treat it as a possible token theft and [revoke the user's sessions](https://brambrinkmeier.com/guides/revoke-sessions-and-verify-entra-id/). ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Refresh tokens in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) 3. [Configurable token lifetimes in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes) 4. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 5. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadnoninteractiveusersigninlogs) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS50173](https://brambrinkmeier.com/entra/aadsts/50173/), [AADSTS70043](https://brambrinkmeier.com/entra/aadsts/70043/), [AADSTS50133](https://brambrinkmeier.com/entra/aadsts/50133/), [AADSTS700081](https://brambrinkmeier.com/entra/aadsts/700081/), [AADSTS7000110](https://brambrinkmeier.com/entra/aadsts/7000110/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS70008: The refresh token has expired or was revoked (fix)", https://brambrinkmeier.com/entra/aadsts/70008/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/70016/ # AADSTS70016: Device code authorization is pending (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/70016/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/70016.json **Short answer:** AADSTS70016 means a device code flow is waiting for the user to sign in. The app polls the token endpoint, nobody has entered the code yet, and Entra answers with 70016. It is the normal reply while a device code is outstanding, not a failure. For defenders it marks the window in which a device code phishing victim has been shown a code but has not used it. **Fix:** Nothing to fix: 70016 is the expected reply while a device code is outstanding. User: finish signing in at the URL the device shows. Developer: keep polling `/token` no more often than every `interval` seconds and stop when the code expires. Admin: block device code flow if nobody needs it. | Field | Value | |---|---| | Code | AADSTS70016 | | Microsoft name | AuthorizationPending | | Category | Tokens and sessions | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Medium: worth a look in context | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-31) | | Last updated | 2026-10-31 | ## What does AADSTS70016 mean? Microsoft's description: > **AuthorizationPending**: OAuth 2.0 device flow error. Authorization is pending. The device will retry polling the request. Nothing is broken. 70016 is the answer the device code flow gives while it waits for a person. The flow has two halves, described on Microsoft's [device authorization grant page](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-device-code). First the app calls `/devicecode` and gets back a `device_code` (*"A long string used to verify the session between the client and the authorization server"*), a `user_code` (*"A short string shown to the user used to identify the session on a secondary device"*) and a `verification_uri` (*"The URI the user should go to with the `user_code` in order to sign in"*). Then, while the person signs in somewhere else, *"the client should be polling the `/token` endpoint for the requested token using the `device_code`."* Every poll that happens before the person has finished gets 70016. Microsoft's protocol-level name for the same condition is in its expected-errors table: | Error | Microsoft's description | Microsoft's client action | |---|---|---| | `authorization_pending` | The user hasn't finished authenticating, but hasn't canceled the flow. | Repeat the request after at least `interval` seconds. | So the correct handling of 70016 is to wait and ask again. An app that treats it as a failure and stops has broken its own sign-in. Codes that do mean something went wrong sit next to it in Microsoft's reference: | Code | Microsoft's description | What happened | |---|---|---| | **70016** | *"AuthorizationPending - OAuth 2.0 device flow error. Authorization is pending. The device will retry polling the request."* | Still waiting. Keep polling. | | **70018** | *"BadVerificationCode - Invalid verification code due to User typing in wrong user code for device code flow. Authorization isn't approved."* | The person mistyped the short code. | | **70019** | *"CodeExpired - Verification code expired. Have the user retry the sign-in."* | Time ran out. Start again. | | **90119** | *"InvalidUserCode - The user code is null or empty."* | No code was submitted. | | **90120** | *"InvalidDeviceFlowRequest - The request was already authorized or declined."* | The code was used once already. | | **65004** | *"UserDeclinedConsent - User declined to consent to access the app."* | The person said no at the consent prompt. | | [7000014](https://brambrinkmeier.com/entra/aadsts/7000014/) | Not in Microsoft's reference. | The `device_code` value itself isn't recognised. | ## Reproduced in the lab On 31 October 2026 an automated lab run requested a device code from a lab tenant and then polled the token endpoint before anyone had signed in. Entra returned: > AADSTS70016: OAuth 2.0 device flow error. Authorization is pending. Continue polling. Note the wording. The reference says *"The device will retry polling the request"*; the message the token endpoint actually returns says *"Continue polling."* If you are matching on message text, match on the part both have. The run then polled again immediately, with no wait. It got the same code and the same message, not a separate too-fast error. That is one observation from one tenant: it does not prove the endpoint never throttles a fast poller, only that an immediate second poll was answered the same way here. **Measured code lifetime.** The device code in this run was issued with `expires_in` of **900 seconds (15 minutes)** and an `interval` of **5 seconds**. Microsoft documents both fields (`expires_in`: *"The number of seconds before the `device_code` and `user_code` expire"*; `interval`: *"The number of seconds the client should wait between polling requests"*) and its page states the default: *"From the moment the request is sent, the user has 15 minutes to sign in. This is the default value for `expires_in`."* The lab value matches that documented default. The `interval` of 5 seconds is not a number Microsoft publishes anywhere we have found, so treat 5 as what this tenant returned on 31 October 2026, not as a guaranteed constant: read `interval` from the response rather than hard-coding it. That 15-minute window is also how long 70016 can keep coming back for a single code, which matters for the phishing case below. No sign-in log row was captured for 70016. See [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? The code on its own, no. It is the expected reply during a device code sign-in, and a healthy tenant that uses the flow produces it constantly. The pattern can matter, because 70016 is exactly what device code phishing looks like while the lure is live. Microsoft's [Conditional Access authentication flows page](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-authentication-flows) is blunt about the flow: *"Device code flow is a high-risk authentication method that can be part of a phishing attack or used to access corporate resources on unmanaged devices."* In that attack the attacker, not the victim, runs the client. The attacker requests a device code, sends the `user_code` and the verification URL to the victim in a message that looks like a legitimate prompt, and polls. Each poll returns 70016 until the victim enters the code; then the attacker's poll returns tokens. So: - **70016 is the lure window.** It is the only part of the attack that is visible before a successful token issue, and it lasts at most the code lifetime measured above. - **A successful device code sign-in is the damage.** Hunt those, with [the token replay and session hijack guide](https://brambrinkmeier.com/guides/detect-token-replay-m365-session-hijack-entra-id/), which covers the device code filters in the sign-in logs and the Conditional Access control that blocks the flow. | Pattern | Likely meaning | |---|---| | Steady 70016 from a tool a user is actively signing into, ending in a success | Normal device code sign-in. | | 70016 for an app nobody in your tenant should be using device code with | Worth a look. Device code works with public client apps, so the client can be anything, anywhere. | | A device code success from an IP or country that never appears for that user, shortly after 70016 polling | The shape of a successful device code phish. Treat as a session compromise and revoke. | | 70016 and nothing else, repeatedly, for the same app | A code was shown and never entered, or a tool that polls and is never completed. Benign on its own. | | [7000014](https://brambrinkmeier.com/entra/aadsts/7000014/) instead of 70016 | A broken client, not a pending authorization. | One honest limit: we did not capture a 70016 sign-in log row, so whether the attacker's polling requests appear in your tenant's logs at all is unconfirmed. The poll names a client and a `device_code`, but no user has approved anything yet, so there may be no user and no tenant row to attribute it to. Build detections on the device code **successes**, which definitely are logged, and use 70016 only as context. ## How do I find it in my logs (KQL)? Which sign-in table 70016 lands in is not documented, and the lab run produced no row to confirm it. Start with a union so you find out for your own tenant: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType in ("70016", "70018", "70019", "90119", "90120") | summarize Rows = count(), LastSeen = max(TimeGenerated), Descriptions = make_set(ResultDescription, 5) by SourceTable, ResultType | sort by Rows desc ``` If that returns nothing, 70016 is not surfaced to your tenant, and the next query is the one that matters. `AuthenticationProtocol` is documented with *"deviceCode"* among its possible values, so you can inventory the flow itself rather than its pending state: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where AuthenticationProtocol == "deviceCode" or OriginalTransferMethod == "deviceCodeFlow" | summarize Sign_ins = count(), Successes = countif(ResultType == "0"), Users = dcount(UserPrincipalName), IPs = make_set(IPAddress, 10), Codes = make_set(ResultType, 10) by SourceTable, AppDisplayName, AppId | sort by Sign_ins desc ``` An app in that list that you did not expect is worth a question whatever its result codes. The exact string stored in `OriginalTransferMethod` can differ between tenants, so confirm it on one known device code row before you rely on that half of the filter. Then look at the successes per user and per location, which is where a phish shows: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where AuthenticationProtocol == "deviceCode" | where ResultType == "0" | summarize Sign_ins = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Apps = make_set(AppDisplayName, 5), IPs = make_set(IPAddress, 10) by UserPrincipalName | sort by Sign_ins desc ``` As a starting point, treat a user's **first ever** device code success as worth reading in full, and any device code success for a user who does not work with shared or input-constrained devices as suspicious. Tune from your own baseline; a tenant that uses the flow for conference room devices will have a large legitimate one. ## How does Conditional Access affect it? - Microsoft says to *"Allow device code flow only where necessary"* and that it *"recommends blocking device code flow wherever possible"*, using a Conditional Access authentication flows policy. Its own example is to allow the flow for conference room devices in one network location and block it everywhere else. - Our reading: a Conditional Access block does not change 70016. The policy is evaluated when the person signs in at the verification URL, so the polling client keeps getting 70016 until the code expires or the person's sign-in is blocked. That ordering is untested in the lab. - Blocking the flow stops the attacker's client as well as the user's, which is the point of blocking it. ## How do I fix AADSTS70016? Nothing is wrong. There is no fix, only correct handling. **For the user:** finish signing in. The device or tool shows a short code and a URL; open the URL, enter the code, and sign in. The tool completes by itself within a few seconds. If you were not expecting a code, and especially if someone sent you one in a message, do not enter it: that is how device code phishing works. Report it instead. **For developers:** 1. Treat 70016 and `authorization_pending` as "not yet", not as an error. Keep polling. 2. Wait at least `interval` seconds between polls, reading `interval` from the `/devicecode` response. 3. Stop when `expires_in` has passed, and surface the expiry to the user so they can start again. 4. Stop on the terminal errors instead of retrying: `authorization_declined`, `bad_verification_code` and `expired_token`. 5. Use MSAL rather than hand-written polling. It implements the wait, the retry and the terminal cases for you. **For admins:** 1. Inventory the flow with the second query. Decide which apps and which devices genuinely need it. 2. If nothing needs it, block device code flow with a Conditional Access authentication flows policy. Start in report-only and exclude break-glass accounts. 3. Tell users that a code arriving in a message or an email is a phishing attempt. The legitimate flow starts on a device in front of them. 4. For a device code success you cannot explain, treat it as a compromised session: [revoke sessions and verify](https://brambrinkmeier.com/guides/revoke-sessions-and-verify-entra-id/). ## Evidence Reproduced in a lab tenant on 2026-10-31 (Device code flow against a lab tenant; scenario: Device code issued but nobody has signed in yet). First line returned: > AADSTS70016: OAuth 2.0 device flow error. Authorization is pending. Continue polling. Lab-run rows naming this code (6; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-31 | Device code issued but nobody has signed in yet | 70016 | 70016 | AADSTS70016: OAuth 2.0 device flow error. Authorization is pending. Continue polling. | | 2026-10-31 | Device code polled too fast | 70016 / 70020 | 70016 | AADSTS70016: OAuth 2.0 device flow error. Authorization is pending. Continue polling. | | 2026-10-31 | Device code redeemed with a different client ID | 70016 / 7000215 / 70002 | 90023 | AADSTS90023: ClientId passed in the request doesn't match the one in cache | | 2026-10-31 | Device code issued but nobody has signed in yet | 70016 | 70016 | AADSTS70016: OAuth 2.0 device flow error. Authorization is pending. Continue polling. | | 2026-10-31 | Device code polled too fast | 70016 / 70020 | 70016 | AADSTS70016: OAuth 2.0 device flow error. Authorization is pending. Continue polling. | | 2026-10-31 | Device code redeemed with a different client ID | 70016 / 7000215 / 70002 | 90023 | AADSTS90023: ClientId passed in the request doesn't match the one in cache | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and the OAuth 2.0 device authorization grant flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-device-code) 3. [Conditional Access: Authentication flows](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-authentication-flows) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS7000014](https://brambrinkmeier.com/entra/aadsts/7000014/), [AADSTS90023](https://brambrinkmeier.com/entra/aadsts/90023/), [AADSTS50059](https://brambrinkmeier.com/entra/aadsts/50059/), [AADSTS90133](https://brambrinkmeier.com/entra/aadsts/90133/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS70016: Device code authorization is pending (fix)", https://brambrinkmeier.com/entra/aadsts/70016/ (CC BY 4.0), last updated 2026-10-31. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/70021/ # AADSTS70021: No matching federated identity credential (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/70021/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/70021.json **Short answer:** AADSTS70021 means a workload sent an external token (from GitHub, Azure DevOps, Kubernetes or another identity provider) and Entra found no federated identity credential on the app or managed identity that matches it. Usually the issuer or subject is wrong, or the credential was created minutes ago and hasn't propagated. It is a configuration error with low attack value. **Fix:** Developer: if you created the credential minutes ago, wait and retry. Otherwise compare the issuer and subject in the error or token with the federated credential, character by character (case-sensitive, no wildcards), and check the audience. Azure DevOps after a rename: update the sc:// subject. | Field | Value | |---|---| | Code | AADSTS70021 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS70021 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS70021 (checked 30 October 2026). Microsoft does document it on two other pages. Microsoft's page on federated identity credential restrictions quotes the message: > AADSTS70021: No matching federated identity record found for presented assertion. It gives it in one specific context, propagation after setup: > It takes time for the federated identity credential to be propagated throughout a region after being initially configured. A token request made several minutes after configuring the federated identity credential may fail because the cache is populated in the directory with old data. Microsoft's Azure DevOps troubleshooting page lists two longer forms of the same message, with the values from the token appended: | Message (Azure DevOps doc) | Cause Microsoft gives | |---|---| | `No matching federated identity record found for presented assertion. Assertion Issuer: 'https://app.vstoken.visualstudio.com'.` | *"No federated credential was created or the issuer URL isn't correct."* | | `No matching federated identity record found for presented assertion. Assertion Issuer: 'https://login.microsoftonline.com/'. Assertion Subject: 'sc:////'.` | *"Either the issuer URL or the federation subject doesn't match. The Azure DevOps organization or project was renamed or a manually created service connection was renamed without updating the federation subject on the identity."* | Background: with workload identity federation, a workload outside Entra (a GitHub Actions job, an Azure DevOps pipeline, a Kubernetes pod) gets a token from its own identity provider and exchanges it for an Entra access token. Microsoft's overview: *"Microsoft identity platform checks the trust relationship on the user-assigned managed identity or app registration and validates the external token against the OpenID Connect (OIDC) issuer URL on the external IdP."* The trust is a federated identity credential with three values. The Graph overview says they *"must match exactly"*, case-sensitively, against the token's `iss`, `sub` and `aud` claims. 70021 means no credential on the app matched. Our reading: 70021 is the general "no match" code. The more specific codes say which value failed: [700211](https://brambrinkmeier.com/entra/aadsts/700211/) (issuer), [700212](https://brambrinkmeier.com/entra/aadsts/700212/) (audience), [700213](https://brambrinkmeier.com/entra/aadsts/700213/) (subject) and [7002138](https://brambrinkmeier.com/entra/aadsts/7002138/) (subject differs only in letter case). If the app has no federated credentials at all, you get [70025](https://brambrinkmeier.com/entra/aadsts/70025/) instead. Microsoft doesn't document when Entra returns 70021 rather than one of the specific codes. One related code *is* in the reference: AADSTS700229 ForbiddenTokenType, *"Only app-only tokens can be used as Federated Identity Credentials for Microsoft Entra issuer"*. ## Is it an attack? Almost never. It is a mismatch between what a workload sends and what the app trusts. | Pattern | Likely meaning | |---|---| | A new credential, and the first run fails within minutes | Propagation delay, as Microsoft describes. Retry after a short wait. | | An Azure DevOps pipeline that worked and now fails | The organization, project or service connection was renamed, so the `sc://` subject changed. Microsoft's cause. | | A pipeline or workflow that never worked | Wrong issuer or subject on the credential. Microsoft's create-trust page: a wrong subject is saved *"without error. The error does not become apparent until the token exchange fails."* | | Failures for your app from an IP and identity provider you don't use | Someone presenting a token from their own provider with your app's client ID. Likely it fails exactly because no credential trusts that provider, but we haven't tested this. Worth a look, not an incident. | Our reading: the attack to watch for is the opposite case. An attacker who can edit your app registration adds a federated credential that trusts their own provider, and then signs in **successfully**. That shows as a success with a new `FederatedCredentialId`, plus an audit event, not as 70021. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 70021 lands in. An app registration's federated sign-in is a service principal sign-in, so the failure probably lands in `AADServicePrincipalSignInLogs`. Microsoft's service principal sign-ins page says managed identity sign-ins are *"included only in the managed identity sign-in log"*, so a failing user-assigned managed identity may log there instead (`AADManagedIdentitySignInLogs`). Check where it lands in your tenant: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "70021" or ResultSignature == "70021" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable ``` The `ResultSignature` check is there because the Azure Monitor reference describes `ResultType` in `AADServicePrincipalSignInLogs` only as *"Success or Failure"*. Look at a failed row to see which column carries the code in your workspace. For an app that worked before and now fails, find its last successful federated sign-in and which credential it used. The Graph sign-in reference lists `federatedIdentityCredential` as a value of `clientCredentialType`, and describes `federatedCredentialId` as *"the identifier of an application's federated identity credential, if a federated identity credential was used to sign in"*. That the Log Analytics columns carry the same values is our reading: ```kusto let failing = AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "70021" or ResultSignature == "70021" | distinct AppId; AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where AppId in (failing) | where ClientCredentialType == "federatedIdentityCredential" | where ResultType == "0" | summarize arg_max(TimeGenerated, FederatedCredentialId, IPAddress) by AppId, ServicePrincipalName ``` Then check whether someone changed the app's federated credentials around that time. A third-party write-up (trackr.live) reports that this logs as `Update application` with a modified property named `FederatedIdentityCredentials`. Microsoft doesn't document that property name on the pages we checked, so treat this as a starting point: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where OperationName == "Update application" | mv-expand Target = TargetResources | mv-expand Prop = Target.modifiedProperties | where tostring(Prop.displayName) == "FederatedIdentityCredentials" | project TimeGenerated, App = tostring(Target.displayName), Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)), OldValue = tostring(Prop.oldValue), NewValue = tostring(Prop.newValue) ``` The same write-up says credentials on a user-assigned managed identity are an Azure Resource Manager write and don't appear in the Entra audit log. Look in the Azure activity log for those. ## How do I fix AADSTS70021? **For developers and pipeline owners:** 1. If you created the credential minutes ago, wait and retry. Microsoft: *"wait a short time after adding the federated identity credential before requesting a token"*, and add retry logic to token requests. 2. Read the issuer and subject from the error message (the Azure DevOps forms include them) or from your provider's token, and compare them character by character with the credential. Matching is case-sensitive and *"Wildcard characters aren't supported in any federated identity credential property value."* 3. Check the formats Microsoft gives: - GitHub Actions: issuer `https://token.actions.githubusercontent.com` (Microsoft's page shows it both with and without a trailing slash; match your token's `iss`); subject `repo:/:environment:` for jobs tied to an environment, otherwise `repo:/:ref:`, or `repo:/:pull-request`. - Kubernetes: issuer is the cluster's OIDC issuer URL; subject `system:serviceaccount::`. - Azure DevOps: see the issuer table on Microsoft's troubleshooting page. New service connections use `https://login.microsoftonline.com//v2.0`. 4. Check the audience. Microsoft recommends `api://AzureADTokenExchange`. If only the audience is wrong, you may see [700212](https://brambrinkmeier.com/entra/aadsts/700212/). **For admins:** 1. For Azure DevOps after a rename, Microsoft names the cause but gives no fix. Update the federation subject on the app or managed identity to the new `sc://` value. For a wrong issuer, Microsoft's fix is to edit and save the service connection. If Azure DevOps didn't create the identity, update the issuer yourself. 2. An app or user-assigned managed identity can hold at most 20 federated credentials. If you need one per branch or environment, plan for that limit. 3. If failures come from a provider you don't use, confirm no unexpected federated credential exists on the app, and review who can edit the app registration. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. Lab-run rows naming this code (15; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Federated credential: subject does not match | 700213 / 70021 | 700213 | AADSTS700213: No matching federated identity record found for presented assertion subject '{guid}'. Check your federated identity | | 2026-10-30 | Federated credential: issuer does not match | 700211 / 70021 | 700211 | AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id} | | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-30 | Federated credential: subject does not match | 700213 / 70021 | 700213 | AADSTS700213: No matching federated identity record found for presented assertion subject '{guid}'. Check your federated identity | | 2026-10-30 | Federated credential: issuer does not match | 700211 / 70021 | 700211 | AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id} | | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-30 | Federated credential: subject does not match | 700213 / 70021 | 700213 | AADSTS700213: No matching federated identity record found for presented assertion subject '{guid}'. Check your federated identity | | 2026-10-30 | Federated credential: issuer does not match | 700211 / 70021 | 700211 | AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id} | | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-31 | Federated credential: subject does not match | 700213 / 70021 | 700213 | AADSTS700213: No matching federated identity record found for presented assertion subject '{guid}'. Check your federated identity | | 2026-10-31 | Federated credential: issuer does not match | 700211 / 70021 | 700211 | AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id} | | 2026-10-31 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-31 | Federated credential: subject does not match | 700213 / 70021 | 700213 | AADSTS700213: No matching federated identity record found for presented assertion subject '{guid}'. Check your federated identity | | 2026-10-31 | Federated credential: issuer does not match | 700211 / 70021 | 700211 | AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id} | | 2026-10-31 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/lb-lu/entra/identity-platform/reference-error-codes) 2. [Important considerations and restrictions for federated identity credentials](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-considerations) 3. [Troubleshoot an Azure Resource Manager workload identity service connection (Azure DevOps)](https://learn.microsoft.com/en-us/azure/devops/pipelines/release/troubleshoot-workload-identity) 4. [Workload identity federation](https://learn.microsoft.com/entra/workload-id/workload-identity-federation) 5. [Configure an app to trust an external identity provider](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust) 6. [Overview of federated identity credentials (Microsoft Graph)](https://learn.microsoft.com/graph/api/resources/federatedidentitycredentials-overview) 7. [What are service principal sign-ins in Microsoft Entra?](https://learn.microsoft.com/en-my/entra/identity/monitoring-health/concept-service-principal-sign-ins) 8. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) 9. [signIn resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/azure/active-directory/active-directory-reporting-api-sign-in-activity-reference) 10. [A Federated Identity Credential Adds No Secret (trackr.live, third-party)](https://www.trackr.live/?p=1229) ## Related codes [AADSTS700211](https://brambrinkmeier.com/entra/aadsts/700211/), [AADSTS700212](https://brambrinkmeier.com/entra/aadsts/700212/), [AADSTS700213](https://brambrinkmeier.com/entra/aadsts/700213/), [AADSTS7002138](https://brambrinkmeier.com/entra/aadsts/7002138/), [AADSTS70025](https://brambrinkmeier.com/entra/aadsts/70025/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS70021: No matching federated identity credential (fix)", https://brambrinkmeier.com/entra/aadsts/70021/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/70025/ # AADSTS70025: App has no federated identity credentials (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/70025/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/70025.json **Short answer:** AADSTS70025 means a workload presented an external token for an app registration or managed identity that has no federated identity credentials at all. Usually the credential was never created, was deleted, or the pipeline points at the wrong client ID. Users also report it when a certificate assertion was expected. A configuration error with low attack value. **Fix:** Developer: check that the workload sends the client ID of the app or managed identity you configured. Admin: add a federated identity credential on it (Certificates & secrets > Federated credentials), then wait for it to propagate before the first run. | Field | Value | |---|---| | Code | AADSTS70025 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS70025 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS70025 (checked 30 October 2026). Microsoft's Azure DevOps troubleshooting page does: > **AADSTS70025: Client application has no configured federated identity credentials** > Make sure federated credentials are configured on the App registration or Managed Identity. With workload identity federation, the workload sends a token from its own provider (GitHub, Azure DevOps, Kubernetes) as `client_assertion`, and Entra compares it with the federated identity credentials on the app or user-assigned managed identity named by the client ID. 70025 means that list is empty. Our reading: this is the step before the matching codes. If at least one credential exists but none matches, you get [70021](https://brambrinkmeier.com/entra/aadsts/70021/), [700211](https://brambrinkmeier.com/entra/aadsts/700211/) (issuer), [700212](https://brambrinkmeier.com/entra/aadsts/700212/) (audience), [700213](https://brambrinkmeier.com/entra/aadsts/700213/) (subject) or [7002138](https://brambrinkmeier.com/entra/aadsts/7002138/) (subject case). If the client ID doesn't exist in the tenant at all, you get [700016](https://brambrinkmeier.com/entra/aadsts/700016/) instead. Users also report 70025 in a case Microsoft doesn't describe. On Microsoft Q&A, a user signing in with a **certificate** (a self-signed JWT sent as `client_assertion`, not federation) got *"AADSTS70025: Client application has no configured federated identity credentials."* A second user reported the same with a certificate and a JWT assertion built in Python. The thread doesn't confirm a cause. Our reading, untested: Entra decided the assertion was an external token rather than a certificate assertion, so it looked for federated credentials. If you hit this with a certificate, check that the certificate is uploaded to the same app the client ID names, and how your library builds the assertion. ## Reproduced in the lab On 30 October 2026 an automated lab run set this up in my own tenant: one app registration presents its access token as a client assertion, and a second app carries the federated identity credential that is supposed to accept it. With **no federated credential on the target app at all**, Entra returned `AADSTS70025`: > AADSTS70025: The client ''() has no configured federated identity credentials. The message names the client ID and the app's display name, so you can tell straight away which registration is missing the credential. This is the code you get when the credential was never created, or was created on a different app than the one in the request. The sign-in log row isn't captured yet; see [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? No. | Pattern | Likely meaning | |---|---| | A new pipeline or workflow fails on its first run | The federated credential was never created on this app or managed identity. | | A pipeline points at a different app than the one you configured | The client ID in the pipeline or secret is another app registration with no credentials. In AL-Go issue 1147, a preview build of the tool read its credentials from a different GitHub secret than its docs said, and the maintainer called it a bug. | | It worked before and now fails | Someone deleted the app's last federated credential, or the pipeline now targets another app. Check the audit log (below). | | A certificate-based app fails with 70025 | Users report this. The cause is unconfirmed; see above. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 70025 lands in. App registration failures probably land in `AADServicePrincipalSignInLogs`; Microsoft says managed identity sign-ins are in the managed identity sign-in log *"only"*, so a user-assigned managed identity may log there instead. Check: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs, AADManagedIdentitySignInLogs | where TimeGenerated > ago(30d) | where ResultType == "70025" or ResultSignature == "70025" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable ``` Failures per app. `ClientCredentialType` is documented as *"The type of client credential used. Examples include client assertion, client secret, etc."* Seeing which type Entra recorded may help with the certificate case; that it is filled in on a failure is our assumption: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "70025" or ResultSignature == "70025" | summarize Failures = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), CredentialTypes = make_set(ClientCredentialType, 5), IPs = make_set(IPAddress, 10) by AppId, ServicePrincipalName | sort by Failures desc ``` If the app had a credential before, look for its removal. A third-party write-up (trackr.live) reports that federated credential changes on an app registration log as `Update application` with a modified property `FederatedIdentityCredentials`; Microsoft doesn't document that name on the pages we checked: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where OperationName == "Update application" | mv-expand Target = TargetResources | mv-expand Prop = Target.modifiedProperties | where tostring(Prop.displayName) == "FederatedIdentityCredentials" | project TimeGenerated, App = tostring(Target.displayName), Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)), OldValue = tostring(Prop.oldValue), NewValue = tostring(Prop.newValue) ``` The same write-up says changes on a user-assigned managed identity are Azure Resource Manager writes and appear in the Azure activity log, not the Entra audit log. ## How do I fix AADSTS70025? **For developers and pipeline owners:** 1. Check which client ID the workload sends, and that it is the app or managed identity you configured. 2. If you meant to use a certificate or secret, check the tool really sends that. In AL-Go issue 1147 the user's workaround was to go back from the preview to the `@main` version of the tool. **For admins:** 1. Add a federated identity credential on that app registration (**Certificates & secrets** > **Federated credentials**) or on the user-assigned managed identity. Microsoft's create-trust page lists the issuer and subject values for GitHub, Kubernetes and other providers. 2. Wait before the first run. Microsoft's restrictions page says a new credential takes time to propagate and early requests can fail with [70021](https://brambrinkmeier.com/entra/aadsts/70021/). 3. If a credential was deleted and nobody meant to, find out who did it from the audit log before recreating it. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Client-credentials token request with a federated identity credential, against a lab tenant; scenario: Federated credential: no credential configured at all). First line returned: > AADSTS70025: The client ''() has no configured federated identity credentials. Lab-run rows naming this code (5; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Federated credential: no credential configured at all | 70025 | 70025 | AADSTS70025: The client '{app-id}'(lab-fic-target-41136574530) has no configured federated identity credentials. | | 2026-10-30 | Federated credential: no credential configured at all | 70025 | 70025 | AADSTS70025: The client '{app-id}'(lab-fic-target-41139925607) has no configured federated identity credentials. | | 2026-10-30 | Federated credential: no credential configured at all | 70025 | 70025 | AADSTS70025: The client '{app-id}'(lab-fic-target-41143330001) has no configured federated identity credentials. | | 2026-10-31 | Federated credential: no credential configured at all | 70025 | 70025 | AADSTS70025: The client '{app-id}'(lab-fic-target-41146039117) has no configured federated identity credentials. | | 2026-10-31 | Federated credential: no credential configured at all | 70025 | 70025 | AADSTS70025: The client '{app-id}'(lab-fic-target-41150019626) has no configured federated identity credentials. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/lb-lu/entra/identity-platform/reference-error-codes) 2. [Troubleshoot an Azure Resource Manager workload identity service connection (Azure DevOps)](https://learn.microsoft.com/en-us/azure/devops/pipelines/release/troubleshoot-workload-identity) 3. [Why am I receiving this error AADSTS70025 (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/2071328/why-am-i-receiving-this-error-aadsts70025-client-a) 4. [AL-Go issue 1147 (GitHub)](https://github.com/microsoft/AL-Go/issues/1147) 5. [Configure an app to trust an external identity provider](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust) 6. [Important considerations and restrictions for federated identity credentials](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-considerations) 7. [What are service principal sign-ins in Microsoft Entra?](https://learn.microsoft.com/en-my/entra/identity/monitoring-health/concept-service-principal-sign-ins) 8. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) 9. [A Federated Identity Credential Adds No Secret (trackr.live, third-party)](https://www.trackr.live/?p=1229) ## Related codes [AADSTS70021](https://brambrinkmeier.com/entra/aadsts/70021/), [AADSTS700211](https://brambrinkmeier.com/entra/aadsts/700211/), [AADSTS700212](https://brambrinkmeier.com/entra/aadsts/700212/), [AADSTS700213](https://brambrinkmeier.com/entra/aadsts/700213/), [AADSTS7002138](https://brambrinkmeier.com/entra/aadsts/7002138/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS700226](https://brambrinkmeier.com/entra/aadsts/700226/), [AADSTS7002121](https://brambrinkmeier.com/entra/aadsts/7002121/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS70025: App has no federated identity credentials (fix)", https://brambrinkmeier.com/entra/aadsts/70025/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/70043/ # AADSTS70043: Refresh token expired due to sign-in frequency checks Canonical: https://brambrinkmeier.com/entra/aadsts/70043/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/70043.json **Short answer:** AADSTS70043 means a refresh token was refused because a Conditional Access sign-in frequency policy says the user must authenticate again. It is the session control working as configured, so it is expected and has low attack value. Volume tracks how strict your policy is. Hunt it in AADNonInteractiveUserSignInLogs with ResultType == "70043". **Fix:** Nothing to fix: a Conditional Access sign-in frequency policy is working as configured. User: sign in again when the app asks. Admin: if users get too many prompts, change the interval in the policy (Conditional Access > Policies > Session > Sign-in frequency). | Field | Value | |---|---| | Code | AADSTS70043 | | Microsoft name | BadTokenDueToSignInFrequency | | Category | Tokens and sessions | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-25 | ## What does AADSTS70043 mean? Microsoft's description: > **BadTokenDueToSignInFrequency**: The refresh token has expired or is invalid due to sign-in frequency checks by Conditional Access. The token was issued on {issueDate} and the maximum allowed lifetime for this request is {time}. An app tried to use a refresh token silently. A Conditional Access policy with a sign-in frequency session control says the user's last authentication is too old for this request. The app has to send the user to an interactive sign-in. ## Is it an attack? See the [comparison of the codes behind "asked to sign in again"](https://brambrinkmeier.com/guides/why-user-asked-to-sign-in-again-entra-id/) (70043, 700082, 50173, 50133, 50076). No. 70043 is a control you configured doing its job. Expect it wherever you have a sign-in frequency policy, and expect more of it the shorter the interval. | Pattern | Likely meaning | |---|---| | 70043 for a user, followed by an interactive success in `SigninLogs` from the same IP and device | Normal re-authentication. Benign. | | A jump in 70043 volume on a specific day | Someone created or tightened a sign-in frequency policy. Check your Conditional Access change history. | | 70043 for a user from an IP or device they don't use, with no interactive sign-in following | An old refresh token being presented from somewhere unexpected. This is reasoning, not a documented detection: the control stopped it, but the token existed somewhere it shouldn't. Investigate as a possible stolen token. | The message includes the token's issue date and the maximum allowed lifetime, so it tells you how old the token was when it was refused. **IP caveat for confidential clients.** Microsoft's [non-interactive sign-ins page](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) says: *"The IP address of non-interactive sign-ins performed by confidential clients doesn't match the actual source IP of where the refresh token request is coming from. Instead, it shows the original IP used for the original token issuance."* So an unfamiliar IP is a weaker stolen-token signal for confidential clients: it may only show where the token was first issued. The second query below inherits that limit. ## How do I find it in my logs (KQL)? Which apps and policies generate the volume: ```kusto AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "70043" | summarize Rows = count(), Users = dcount(UserPrincipalName), IPs = dcount(IPAddress) by AppDisplayName, ResourceDisplayName | sort by Rows desc ``` The rare case worth a look: 70043 from an IP where the same user had no successful sign-in in the previous 30 days. ```kusto let lookback = 30d; let knownUserIPs = union (SigninLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType), (AADNonInteractiveUserSignInLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType) | where TimeGenerated > ago(lookback) | where ResultType == "0" | distinct UserPrincipalName, IPAddress; AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "70043" | join kind=leftanti knownUserIPs on UserPrincipalName, IPAddress | extend Location = parse_json(LocationDetails) | project TimeGenerated, UserPrincipalName, IPAddress, Country = tostring(Location.countryOrRegion), AppDisplayName, UserAgent, ResultDescription | sort by TimeGenerated desc ``` `ResultType` is a **string** column, so compare it with `"70043"`, not `70043`. `LocationDetails` is a string in this table, hence `parse_json`. Non-interactive rows are aggregated when application, user, IP address, status and resource match, so row counts are not request counts. ## How does Conditional Access affect it? - The cause is a Conditional Access **session control**: sign-in frequency. Microsoft's default, with no such policy, is *"a rolling window of 90 days."* - A shorter interval means more 70043 rows and more prompts. Microsoft warns: *"Triggering reauthentication too frequently can increase security friction to a point that it causes users to experience MFA fatigue and open the door to phishing."* - The re-authentication after a 70043 is a normal sign-in. It goes through MFA and the rest of your Conditional Access policies. ## Why do users keep getting prompted again? Sign-in frequency applies to most Microsoft native apps, Microsoft web apps (Office.com, Exchange Online, SharePoint and OneDrive, the Teams web client, the Azure portal) and to non-Microsoft SAML and OAuth2/OIDC apps that redirect back to Entra ID regularly. Two device details explain most "I just signed in" complaints: - On **Microsoft Entra joined and hybrid joined** devices, unlocking the device or signing in interactively refreshes the Primary Refresh Token (PRT) every four hours, and the PRT must fall inside the sign-in frequency window. - On **Microsoft Entra registered** devices, unlocking the device does not satisfy the policy. The Entra WAM plugin can refresh the PRT while a native app authenticates. Microsoft also warns that persistent browser cookies ("Stay signed in?") can keep Entra artifacts usable until the token expires, regardless of Conditional Access. Review that setting if you rely on short intervals as a security control. ## How is 70043 different from 700082 and 50076? All three can show up when a user is asked to sign in again, but they have different causes. | Code | Cause | Attack value | |---|---|---| | **70043** | A Conditional Access sign-in frequency policy refused the refresh token | Low | | [700082](https://brambrinkmeier.com/entra/aadsts/700082/) | The refresh token sat unused until it expired from inactivity | Low | | [50076](https://brambrinkmeier.com/entra/aadsts/50076/) | Microsoft's description: a configuration change by the admin, such as a Conditional Access policy, per-user enforcement, or a new location, means the user must use multifactor authentication | Check the pattern | The text "Strong Authentication is required" is Microsoft's description for [50074](https://brambrinkmeier.com/entra/aadsts/50074/), and 50076 has its own wording about a configuration change that requires MFA. The refresh-token text with "sign-in frequency" belongs to 70043. If you searched on either message, match the code in your sign-in log first. ## How do I fix AADSTS70043? **For the user:** sign in again when the app asks. This is expected behavior, not an error on your side. **For admins:** 1. Nothing is broken. If users complain about too many prompts, check which policy sets the interval with the first query and the policy list on the matching interactive sign-in. 2. To change the interval, open the policy in the Microsoft Entra admin center under Conditional Access > Policies, then Session > Sign-in frequency. Microsoft's default with no policy is a rolling 90 days. 3. Reserve short sign-in frequency intervals for high-risk apps, users or unmanaged devices, rather than everyone. 4. If the second query returns a row you can't explain, treat the user's tokens as exposed: revoke the sessions and check the user's recent sign-ins. Microsoft documents `Revoke-MgUserSignInSession` for explicit revocation. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Conditional Access: session lifetime](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-session-lifetime) 3. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 4. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadnoninteractiveusersigninlogs) ## Related codes [AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS50173](https://brambrinkmeier.com/entra/aadsts/50173/), [AADSTS50133](https://brambrinkmeier.com/entra/aadsts/50133/), [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/), [AADSTS50089](https://brambrinkmeier.com/entra/aadsts/50089/), [AADSTS50196](https://brambrinkmeier.com/entra/aadsts/50196/), [AADSTS70008](https://brambrinkmeier.com/entra/aadsts/70008/), [AADSTS70044](https://brambrinkmeier.com/entra/aadsts/70044/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS70043: Refresh token expired due to sign-in frequency checks", https://brambrinkmeier.com/entra/aadsts/70043/ (CC BY 4.0), last updated 2026-10-25. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/70044/ # AADSTS70044: Session expired by sign-in frequency checks (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/70044/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/70044.json **Short answer:** AADSTS70044 means a Conditional Access sign-in frequency check ended the user's session, so the app must send the user to an interactive sign-in. Microsoft's error reference doesn't list it; the wording comes from a Microsoft Q&A answer. It is the session control working, with low attack value. The app should handle it by prompting, not by retrying silently. **Fix:** User: sign in again when the app asks; if it never prompts, close the app fully, reopen it and sign in. Developer: don't retry silently; force an interactive sign-in with prompt=login (OAuth/OIDC) or forceAuthN=true (SAML) on this error only. Admin: check the sign-in frequency policy. | Field | Value | |---|---| | Code | AADSTS70044 | | Category | Tokens and sessions | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS70044 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS70044 (checked 30 October 2026). The wording below comes from a Microsoft Q&A thread, not from a Microsoft documentation page. A Q&A moderator (AmanpreetSingh-MSFT) quoted it in an answer: > AADSTS70044: The session has expired or is invalid due to sign-in frequency checks by conditional access. The person who asked quoted the sign-in log failure reason as *"The session has expired or is invalid due to sign-in frequency checks by conditional access. MFA requirement satisfied by claim in the token."* In that thread, a Conditional Access policy set sign-in frequency to one hour for a VPN app. The moderator said the backend trace showed the credential was authenticated on one day and presented the next, outside the one-hour window, so it was ignored. The same thread says old credentials are usually reused during silent authentication, through a refresh token or a Primary Refresh Token (PRT). A second Q&A thread describes users with several browsers hitting "error code 70044" under a 30-day sign-in frequency policy. That thread gives no full message text. Our reading: 70044 is the session-side sibling of [70043](https://brambrinkmeier.com/entra/aadsts/70043/), which Microsoft does list. 70043 says the **refresh token** is too old for the sign-in frequency policy. 70044 says the **session** is. Both mean the same thing for the user: sign in again. Microsoft doesn't document the difference. ## Is it an attack? Usually not. Users report it where a sign-in frequency policy exists, and it is the policy doing what it was configured to do. | Pattern | Likely meaning | |---|---| | 70044 for many users shortly after a new or tightened sign-in frequency policy | The policy is now enforced. Expected. | | 70044 for one user, repeating every few minutes, never followed by a success | The app keeps retrying silently and never prompts. An app bug, not an attack. Our interpretation. | | 70044 for a user who works in several browsers | Each browser keeps its own cookies and session, so a new browser or cleared cookies starts a new sign-in. This is from a Q&A answer, not from Microsoft documentation. | | 70044 from an IP or device the user never uses | An old session presented from somewhere unexpected. Our reasoning, not a documented detection: the control stopped it, but check the user's other sign-ins. | One user report adds a caution. In Q&A 852942, revoking the user's sessions fixed the error only until the next day, and the person who asked later concluded the real cause was AD FS extranet lockout. That is their own conclusion, not a Microsoft answer, but it shows that 70044 can be the visible symptom of a different problem in federated tenants. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 70044 is logged in. Check where it lands in your workspace first: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "70044" | summarize Rows = count() by SourceTable ``` Which apps and session policies produce it. `SessionLifetimePolicies` is documented as *"any conditional access session management policies that were applied during the sign-in event."* It is a string in both tables: ```kusto union (SigninLogs | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, ClientAppUsed, SessionLifetimePolicies), (AADNonInteractiveUserSignInLogs | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, ClientAppUsed, SessionLifetimePolicies) | where TimeGenerated > ago(7d) | where ResultType == "70044" | summarize Rows = count(), Users = dcount(UserPrincipalName) by AppDisplayName, ClientAppUsed, SessionLifetimePolicies | sort by Rows desc ``` Users stuck in a loop: many 70044 rows in a day and no success on the same app. The threshold of 20 is a starting point; tune it to your volume. ```kusto let window = 1d; let fails = union (SigninLogs | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName), (AADNonInteractiveUserSignInLogs | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName) | where TimeGenerated > ago(window) | where ResultType == "70044" | summarize Fails = count(), LastFail = max(TimeGenerated) by UserPrincipalName, AppDisplayName | where Fails >= 20; let successes = union (SigninLogs | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName), (AADNonInteractiveUserSignInLogs | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName) | where TimeGenerated > ago(window) | where ResultType == "0" | distinct UserPrincipalName, AppDisplayName; fails | join kind=leftanti successes on UserPrincipalName, AppDisplayName | sort by Fails desc ``` ## How does Conditional Access affect it? - The trigger users report is a Conditional Access **sign-in frequency** session control. Microsoft's default without such a policy is *"a rolling window of 90 days."* - With **Every time**, Microsoft says the policy *"requires full reauthentication when the session is evaluated"* and *"factors in five minutes of clock skew"*. Microsoft also warns that every-time reauthentication without MFA *"might result in sign-in looping for your users."* - On Microsoft Entra joined and hybrid joined devices, Microsoft says unlocking the device or signing in interactively refreshes the PRT every four hours, and the PRT's last refresh must fall inside the sign-in frequency window. On Microsoft Entra registered devices, unlocking doesn't satisfy the policy. ## How do I fix AADSTS70044? **For the user:** sign in again when the app asks. If the app never shows a sign-in prompt and keeps failing, close it fully, open it again, and sign in. If that doesn't help, tell IT the app name and the time. **For developers:** treat 70044 like any interaction-required result. Don't retry silently. The Q&A moderator's advice: force an interactive sign-in with `prompt=login` for OAuth and OpenID Connect, or `forceAuthN=true` for SAML. In the thread, `forceAuthN=true` worked but made every user type their username again, so use it only on this error, not on every sign-in. **For admins:** 1. Find the policy. Open the failed sign-in in the Microsoft Entra admin center and check the Conditional Access tab, or use the second query above. 2. If the interval is shorter than the app can handle, lengthen it or scope the policy to the apps and users that need it. Microsoft advises to *"limit the number of applications that enforce a policy requiring users to reauthenticate every time."* 3. For a single user who keeps failing on a joined device, check that the device's PRT refreshes. The Q&A moderator suggested comparing the event log **Applications and Services Logs > Microsoft > Windows > AAD > Operational** between a working and a failing user. 4. In a federated tenant, rule out AD FS problems such as extranet lockout before you change the policy. That cause comes from one user report. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Azure AD Signin Issue (Microsoft Q&A 852942)](https://learn.microsoft.com/en-us/answers/questions/852942/azure-ad-signin-issue) 3. [Conditional access and multiple browsers (Microsoft Q&A 5553648)](https://learn.microsoft.com/en-us/answers/questions/5553648/conditional-access-and-multiple-browsers) 4. [Conditional Access: session lifetime](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-session-lifetime) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 6. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/AADNonInteractiveUserSignInLogs) ## Related codes [AADSTS70043](https://brambrinkmeier.com/entra/aadsts/70043/), [AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/), [AADSTS50133](https://brambrinkmeier.com/entra/aadsts/50133/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS70044: Session expired by sign-in frequency checks (fix)", https://brambrinkmeier.com/entra/aadsts/70044/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/75011/ # AADSTS75011: Sign-in method doesn't match what the app asked for (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/75011/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/75011.json **Short answer:** AADSTS75011 means a SAML app asked for a specific authentication method in its request, and the method the user already signed in with is different. Microsoft Entra ID reuses the existing session instead of signing the user in again, so the two don't match. It is a configuration problem with low attack value. Fix it by removing RequestedAuthnContext or adding ForceAuthn. **Fix:** Developer or vendor: remove RequestedAuthnContext from the SAML AuthnRequest, or keep it and send ForceAuthn=true so the user signs in fresh. Admin: ask the app vendor for that change; it is made in the app, not in Entra ID. User: report it to the app owner with the time. | Field | Value | |---|---| | Code | AADSTS75011 | | Microsoft name | NoMatchedAuthnContextInOutputClaims | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS75011 mean? Microsoft's description: > **NoMatchedAuthnContextInOutputClaims**: The authentication method by which the user authenticated with the service doesn't match requested authentication method. To learn more, see the troubleshooting article for error [AADSTS75011](https://learn.microsoft.com/troubleshoot/azure/active-directory/error-code-aadsts75011-auth-method-mismatch). This is a SAML single sign-on error. The app put a `RequestedAuthnContext` element in its SAML request. That element names the authentication method the app wants, as an `AuthnContextClassRef` value such as `urn:oasis:names:tc:SAML:2.0:ac:classes:Password`. Microsoft's troubleshooting article explains the cause: the user had already signed in before reaching the app, and *"the `AuthnContext` (authentication method) used for that previous authentication is different from the one being requested."* Microsoft Entra ID *"won't perform a fresh authentication request"*. It reuses the authentication context it already has, so the response can't contain the method the app asked for. Microsoft's example is a federated user who signed in to My Apps with Windows Integrated Authentication through AD FS. The session's `AuthnContextClassRef` is then `urn:federation:authentication:windows`, and *"there will be a mismatch if the app requests other than `urn:federation:authentication:windows`."* The article names a second case: a session where MFA was used. ## Is it an attack? No documented attack pattern exists for 75011. It is an agreement problem between the app's SAML request and the user's existing session. Our reading: the sign-in fails before the app receives an assertion, so an attacker gains nothing from it. | Pattern | Likely meaning | |---|---| | 75011 for many users of one SAML app, starting on a specific day | The app (or a change to it) started sending `RequestedAuthnContext`. Configuration. | | 75011 only for federated users | Likely, based on Microsoft's AD FS example: the session came from the federation service with a method the app doesn't accept. | | 75011 only for users who signed in with MFA or a certificate earlier in the session | The session method (for example a certificate or MFA) is stronger or different from the one the app named. Configuration. | | 75011 that goes away when the user opens the app in a private window | Likely the same cause: without an existing session, the user authenticates fresh and the method can match. Unconfirmed. | Exclude it from failure-based attack detections. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 75011 is logged in. Check where it lands in your workspace first: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "75011" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Which apps cause it, and whether the sessions came from a federation service: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "75011" | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), Protocols = make_set(AuthenticationProtocol, 5), Issuers = make_set(TokenIssuerType, 5) by AppDisplayName, AppId | sort by Rows desc ``` `AuthenticationProtocol` is documented with values including `saml20`. A `FirstSeen` date that lines up with a change to the app is the most useful clue. `TokenIssuerType` is documented with values including `AzureAD` and `ADFederationServices`. If `Issuers` shows `ADFederationServices` rather than `AzureAD`, you are likely in Microsoft's AD FS scenario. Users who hit 75011 and then succeeded on the same app the same day, a sign that a fresh sign-in (for example a new browser session) works around it: ```kusto let mismatches = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "75011" | summarize FirstFail = min(TimeGenerated) by UserPrincipalName, AppId, AppDisplayName; let successes = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "0" | summarize LastSuccess = max(TimeGenerated) by UserPrincipalName, AppId; mismatches | join kind=leftouter successes on UserPrincipalName, AppId | extend RecoveredLater = isnotnull(LastSuccess) and LastSuccess > FirstFail | summarize Users = count(), Recovered = countif(RecoveredLater) by AppDisplayName | sort by Users desc ``` `ResultType` is a **string** column, so compare it with `"75011"`, not `75011`. ## How do I fix AADSTS75011? **For the user:** close the browser (or open a private window) and open the app again. That may help because there is no earlier session to reuse. This is not a documented fix. If it still fails, report it to the app's owner with the time of the error. It is not something you can fix on your side. **For developers (the SAML app):** 1. Remove `RequestedAuthnContext` from the `AuthnRequest` if you can. Microsoft calls it *"an optional value"* and its first suggestion is to *"ask the application if the value could be removed"*. 2. If you must keep it, request a fresh sign-in. Microsoft says *"the SAML request must contain the value, `forceAuthn="true"`"*, so the requested method is used. The SAML protocol reference describes `ForceAuthn` as forcing the user *"to reauthenticate, even if they have a valid session with Microsoft Entra ID."* 3. If you keep `RequestedAuthnContext`, set `Comparison` to `exact`. Microsoft's SAML reference says it *"must be set to `exact`"*, and lists the `AuthnContextClassRef` values Microsoft Entra ID supports. Only request one of those. **For admins:** 1. Use the second query to find the app and the date it started. 2. Ask the vendor whether the app can stop sending `RequestedAuthnContext`, or send `ForceAuthn="true"` with it. Both changes are made in the app's SAML request, not in Entra ID. 3. If the app needs MFA, enforce that with a Conditional Access policy on the app instead of asking for it in the SAML request. Our recommendation, not a step from Microsoft's article. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Error AADSTS75011: authentication method doesn't match requested authentication method](https://learn.microsoft.com/troubleshoot/azure/active-directory/error-code-aadsts75011-auth-method-mismatch) 3. [Single sign-on SAML protocol](https://learn.microsoft.com/en-us/entra/identity-platform/single-sign-on-saml-protocol) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 5. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadnoninteractiveusersigninlogs) ## Related codes [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS50074](https://brambrinkmeier.com/entra/aadsts/50074/), [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/), [AADSTS76021](https://brambrinkmeier.com/entra/aadsts/76021/), [AADSTS500031](https://brambrinkmeier.com/entra/aadsts/500031/), [AADSTS750054](https://brambrinkmeier.com/entra/aadsts/750054/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS75011: Sign-in method doesn't match what the app asked for (fix)", https://brambrinkmeier.com/entra/aadsts/75011/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/76021/ # AADSTS76021 fix: SAML request not signed but required Canonical: https://brambrinkmeier.com/entra/aadsts/76021/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/76021.json **Short answer:** AADSTS76021 means a SAML app in Microsoft Entra ID is set to require signed authentication requests, and the request it received wasn't signed, or the signature wasn't where the SAML binding expects it. It follows an admin enabling Require verification certificates. It is a configuration error and the check is working as intended. Low attack value. **Fix:** Admin: check the verification certificate under Enterprise apps > the app > Single sign-on > Verification certificates matches the app's signing key. App owner: sign every AuthnRequest with RSA-SHA256, in the query string for HTTP-Redirect or in the XML `` for HTTP-POST. | Field | Value | |---|---| | Code | AADSTS76021 | | Microsoft name | ApplicationRequiresSignedRequests | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS76021 mean? Microsoft's description: > **ApplicationRequiresSignedRequests**: The request sent by client is not signed while the application requires signed requests This is a SAML error. Microsoft's troubleshooting article says it *"indicates that the client didn't sign the request, but the application requires signed requests. Even if the client signs the request, the signature might not be added according to the SAML binding configuration."* The requirement comes from a setting on the enterprise app. Microsoft: *"To enable the verification of signed requests, select **Require verification certificates** and upload a verification public key that matches with the private key used to sign the request."* Once that is on, Entra ID rejects an `AuthnRequest` it can't verify. Microsoft's list of verification failures includes *"Request not signed, but verification is enabled."* Where the signature goes depends on the binding: - **HTTP-Redirect**: *"the signature is included as a query parameter in the URL"* (`SigAlg` and `Signature`). - **HTTP-POST**: *"the signature is embedded within the XML payload of the SAML message."* *"If the application expects the signature in one location but the request uses another binding type, Microsoft Entra ID rejects the request."* ## Is it an attack? No. The setting exists so Entra ID only accepts requests the real service provider signed. 76021 is that check refusing a request. Microsoft also notes that *"Requestor verification is provided for by only responding to registered Assertion Consumer Service URLs"*, so an unsigned request can't send the response somewhere new. | Pattern | Likely meaning | |---|---| | Every user of one SAML app fails, starting at a known change | Someone enabled **Require verification certificates** and the app doesn't sign its requests. | | Failures began when the app or its proxy was updated | The app now signs with a different key, or uses a different binding. | | Users fail when they open the app from My Apps or the Microsoft 365 app launcher | Microsoft says the setting *"will not allow IDP-initiated authentication requests (like SSO testing feature, MyApps or M365 app launcher) to be validated."* Microsoft doesn't say which error code users see then. Our reading: 76021 is a likely candidate. | Users report it in exactly this shape. In a Microsoft Q&A thread, sign-in worked until the signature verification feature was turned on, then failed with 76021. The moderator's two causes: the app doesn't send a signed request, or the wrong certificate is uploaded. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 76021 lands in. Check your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "76021" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which apps fail, for how many users, and since when. The first failure time tells you when to look in the audit log: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "76021" | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Protocols = make_set(AuthenticationProtocol, 5) by AppDisplayName, AppId | sort by Users desc ``` Who changed the app shortly before the failures began. Microsoft lists **Update service principal** as an audit activity. Our assumption: turning on verification certificates is recorded under it; Microsoft doesn't say so. Set the time window around `FirstSeen`: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where Category == "ApplicationManagement" | where OperationName == "Update service principal" | extend App = tostring(TargetResources[0].displayName), ByUser = tostring(InitiatedBy.user.userPrincipalName) | project TimeGenerated, App, ByUser, Result | sort by TimeGenerated desc ``` `ResultType` is a **string** column, so compare it with `"76021"`. ## How do I fix AADSTS76021? **For the user:** you can't fix this. Tell your IT team which app failed and when. If you opened it from My Apps, also try the app's own sign-in page, since requests started from the portal can't be validated with this setting on. **For the app owner or vendor (service provider):** 1. Sign every SAML `AuthnRequest` with the private key that matches the certificate uploaded in Entra ID. 2. Use RSA-SHA256. Microsoft: *"Only RSA-SHA256 is supported"*, with an admin opt-in for RSA-SHA1. 3. Put the signature where the binding expects it. For HTTP-Redirect it must be in the query string. For HTTP-POST it must be inside the XML `` element. **For admins:** 1. Go to **Entra ID** > **Enterprise apps** > **All applications** > the app > **Single sign-on** > **SAML Certificates** > **Verification certificates** > **Edit**. Check that the uploaded certificate is the one the app signs with and hasn't expired. 2. Check the binding the app uses (HTTP-Redirect or HTTP-POST) matches its SAML configuration, as Microsoft's troubleshooting article says. 3. If the app can't sign requests, clearing **Require verification certificates** removes the requirement. That turns off the protection, so do it only as a deliberate decision. 4. The SSO test button in the admin center doesn't work with this setting on. Microsoft: *"the test experience is disabled as the service provider has to sign the request."* Test from the app's own sign-in page instead. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Error AADSTS76021 - The request sent by client is not signed (Microsoft troubleshooting)](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts76021-request-not-signed) 3. [SAML Request Signature Verification](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/howto-enforce-signed-saml-authentication) 4. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) 5. [AADSTS76021: The request sent by client is not signed (Microsoft Q&A, user report)](https://learn.microsoft.com/en-us/answers/questions/1180113/aadsts76021-the-request-sent-by-client-is-not-sign) ## Related codes [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/), [AADSTS75011](https://brambrinkmeier.com/entra/aadsts/75011/), [AADSTS750054](https://brambrinkmeier.com/entra/aadsts/750054/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS76021 fix: SAML request not signed but required", https://brambrinkmeier.com/entra/aadsts/76021/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/90002/ # AADSTS90002: Tenant not found (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/90002/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/90002.json **Short answer:** AADSTS90002 means the sign-in request named a tenant that Entra can't find. Usually the tenant ID or domain in the app's settings is wrong, the app talks to the wrong cloud, or the domain was derived from an email address and isn't registered. It is a configuration error with low attack value. Check the tenant ID and the cloud endpoint. **Fix:** Developer: check the tenant ID or domain in the authority URL against the real tenant ID (Entra ID > Overview > Properties, or Get-AzTenant), and use the login endpoint of the tenant's cloud. User: report the app name to whoever set it up; you can't fix this yourself. | Field | Value | |---|---| | Code | AADSTS90002 | | Microsoft name | InvalidTenantName | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-25) | | Last updated | 2026-10-30 | ## What does AADSTS90002 mean? Microsoft's description: > **InvalidTenantName**: The tenant name wasn't found in the data store. Check to make sure you have the correct tenant ID. The application developer will receive this error if their app attempts to sign into a tenant that we cannot find. Often, this is because a cross-cloud app was used against the wrong cloud, or the developer attempted to sign in to a tenant derived from an email address, but the domain isn't registered. Every sign-in request names a tenant in its URL, as a tenant ID (a GUID) or a domain: `https://login.microsoftonline.com//...`. 90002 means Entra has no tenant by that name in the cloud the request went to. The "wrong cloud" cause is real because the clouds are separate. Microsoft's national clouds page says *"Each cloud instance is separate from the others and has its own environment and endpoints"* and lists `https://login.microsoftonline.com` (global), `https://login.microsoftonline.us` (US Government) and `https://login.partner.microsoftonline.cn` (China, operated by 21Vianet). A US Government tenant ID sent to the global endpoint is not found, and the other way round. ## Reproduced in the lab On 25 October 2026 an automated lab run sent a token request to a tenant ID that doesn't exist (a random GUID the script generated). Entra returned `AADSTS90002` with this first line: > AADSTS90002: Tenant '{tenant-id}' not found. Check to make sure you have the correct tenant ID and are signing into the correct cloud. That confirms the code and its wording at the token endpoint. Note that the returned message mentions the cloud as well as the tenant ID. No sign-in log row was captured. Our reading: there is no tenant to log it in, because the tenant named in the request doesn't exist, and the request never reached the lab tenant either. See [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? No. It is a configuration error in the app or script that sent the request. | Pattern | Likely meaning | |---|---| | A new app or script fails on its first run | Typo in the tenant ID, or a placeholder value left in the config. | | An app that works in one environment fails in another | The app points at the wrong cloud endpoint for that tenant. | | A multi-tenant app that builds the tenant from the user's email domain | The domain isn't a verified domain of any tenant, as Microsoft's description says. | | An app that worked before and now fails | The tenant was deleted, or the custom domain used as tenant name was removed from it. Our interpretation. | Our reading: tenant discovery by attackers doesn't need this error and doesn't show up in your logs through it. A request to a tenant that doesn't exist reaches no tenant. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 90002 is logged in. It probably lands in none of yours, for the reason in the lab note above. Check anyway; this query is expected to return nothing: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "90002" | summarize Rows = count() by SourceTable ``` What the logs can do is tell you the right value to configure. For an app that fails with 90002, find where it signs in successfully and which tenant that is. `ResourceTenantId` is documented as *"the tenant identifier of the resource referenced in the sign in"*: ```kusto union withsource=SourceTable SigninLogs, (AADServicePrincipalSignInLogs | extend ResourceTenantId = AADTenantId, AppDisplayName = ServicePrincipalName) | where TimeGenerated > ago(30d) | where ResultType == "0" | where AppId == "" | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, ResourceTenantId, AppDisplayName ``` `AADServicePrincipalSignInLogs` has no `ResourceTenantId` or `AppDisplayName` column, so the query uses `AADTenantId` and `ServicePrincipalName` there (our choice; the table reference doesn't describe `AADTenantId`). If this returns your tenant ID and the app config holds a different one, you found the cause. ## How do I fix AADSTS90002? **For the user:** you can't fix this yourself. Report the app name to whoever set it up. **For developers:** 1. Check the tenant ID or domain in the authority URL. Compare it with the real tenant ID; Microsoft's page on finding it says to use **Entra ID** > **Overview** > **Properties** in the Entra admin center, or `Get-AzTenant` in Azure PowerShell. 2. Check the cloud. Microsoft's national clouds page: *"use the endpoints for the cloud instance where you'll deploy the application."* A tenant in US Government or China needs that cloud's login endpoint, not `login.microsoftonline.com`. 3. Don't derive the tenant from the user's email domain unless you handle the case where the domain isn't registered. For a multi-tenant app, sign in through `/organizations` or `/common` and read the tenant from the token instead. **For admins:** 1. Get the correct tenant ID from the admin center or with PowerShell: ```powershell Connect-AzAccount Get-AzTenant ``` 2. If the app uses a domain name as tenant, check that the domain is still verified in your tenant. 3. If the app is a third-party product, give the vendor your tenant ID and tell them which cloud your tenant is in. ## Evidence Reproduced in a lab tenant on 2026-10-25 (ROPC token request against a lab tenant; scenario: Tenant does not exist). First line returned: > AADSTS90002: Tenant '{tenant-id}' not found. Check to make sure you have the correct tenant ID and are signing into the correct cloud. Lab-run rows naming this code (9; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Tenant does not exist | 90002 | 90002 | AADSTS90002: Tenant '{tenant-id}' not found. Check to make sure you have the correct tenant ID and are signing into the correct cloud. | | 2026-10-30 | Tenant does not exist | 90002 | 90002 | AADSTS90002: Tenant '{tenant-id}' not found. Check to make sure you have the correct tenant ID and are signing into the correct cloud. | | 2026-10-30 | Tenant does not exist | 90002 | 90002 | AADSTS90002: Tenant '{tenant-id}' not found. Check to make sure you have the correct tenant ID and are signing into the correct cloud. | | 2026-10-30 | Tenant does not exist | 90002 | 90002 | AADSTS90002: Tenant '{tenant-id}' not found. Check to make sure you have the correct tenant ID and are signing into the correct cloud. | | 2026-10-30 | Tenant does not exist | 90002 | 90002 | AADSTS90002: Tenant '{tenant-id}' not found. Check to make sure you have the correct tenant ID and are signing into the correct cloud. | | 2026-10-30 | Tenant does not exist | 90002 | 90002 | AADSTS90002: Tenant '{tenant-id}' not found. Check to make sure you have the correct tenant ID and are signing into the correct cloud. | | 2026-10-30 | Tenant does not exist | 90002 | 90002 | AADSTS90002: Tenant '{tenant-id}' not found. Check to make sure you have the correct tenant ID and are signing into the correct cloud. | | 2026-10-31 | Tenant does not exist | 90002 | 90002 | AADSTS90002: Tenant '{tenant-id}' not found. Check to make sure you have the correct tenant ID and are signing into the correct cloud. | | 2026-10-31 | Tenant does not exist | 90002 | 90002 | AADSTS90002: Tenant '{tenant-id}' not found. Check to make sure you have the correct tenant ID and are signing into the correct cloud. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [National clouds (Microsoft identity platform)](https://learn.microsoft.com/en-us/entra/identity-platform/authentication-national-cloud) 3. [How to find your Microsoft Entra tenant ID](https://learn.microsoft.com/en-us/entra/fundamentals/how-to-find-tenant) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS16000](https://brambrinkmeier.com/entra/aadsts/16000/), [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/), [AADSTS50059](https://brambrinkmeier.com/entra/aadsts/50059/), [AADSTS50194](https://brambrinkmeier.com/entra/aadsts/50194/), [AADSTS90019](https://brambrinkmeier.com/entra/aadsts/90019/), [AADSTS90133](https://brambrinkmeier.com/entra/aadsts/90133/), [AADSTS900023](https://brambrinkmeier.com/entra/aadsts/900023/), [AADSTS900439](https://brambrinkmeier.com/entra/aadsts/900439/), [AADSTS1002016](https://brambrinkmeier.com/entra/aadsts/1002016/), [AADSTS5000224](https://brambrinkmeier.com/entra/aadsts/5000224/), [AADSTS5000225](https://brambrinkmeier.com/entra/aadsts/5000225/), [AADSTS9002331](https://brambrinkmeier.com/entra/aadsts/9002331/), [AADSTS9002346](https://brambrinkmeier.com/entra/aadsts/9002346/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS90002: Tenant not found (fix)", https://brambrinkmeier.com/entra/aadsts/90002/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/90009/ # AADSTS90009 fix: app requests a token for itself Canonical: https://brambrinkmeier.com/entra/aadsts/90009/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/90009.json **Short answer:** AADSTS90009 means an app asked Microsoft Entra ID for a token where the resource is the app itself, but named itself with an App ID URI or other string instead of its GUID application ID. Microsoft supports that only with the GUID. It is a developer error with no attack value. Use the client ID GUID as the resource, or call the right API. **Fix:** Developer: if the app really needs a token for itself, use its application (client) ID GUID as the resource or scope, for example `/.default`. More often the scope should name a different API: put that API's App ID URI or client ID in the scope instead of your own. | Field | Value | |---|---| | Code | AADSTS90009 | | Microsoft name | TokenForItselfMissingIdenticalAppIdentifier | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS90009 mean? Microsoft's description: > **TokenForItselfMissingIdenticalAppIdentifier**: The application is requesting a token for itself. This scenario is supported only if the resource that's specified is using the GUID-based application ID. In a token request the app names two things: itself (the client, by its application ID) and the API it wants a token for (the resource). Here both point at the same app. Entra ID accepts that only if the resource is given as the app's **GUID application ID**. If the resource is given another way, such as the App ID URI, the request fails with 90009. An app can be named by more than its GUID. Microsoft describes the App ID URI as a string a resource sets *"as its identifier"*, which *"Clients who acquire a token for the API can use … during an OAuth request"*. The service principal's `servicePrincipalNames` hold those URIs. Microsoft recommends `api://` as the format. So a request with resource `api://` or `https://yourdomain/...` can point back at your own app without containing the bare GUID. The full message users report reads: *"AADSTS90009: Application ''() is requesting a token for itself. This scenario is supported only if resource is specified using the GUID based App Identifier."* ## Is it an attack? No. A request that names itself badly gets nothing. Users report it in three situations: | Pattern | Likely meaning | |---|---| | An MSAL.js app gets 90009 from `acquireTokenSilent` when asking for a token for its own App Service API | Reported in Microsoft Q&A. The thread doesn't show the scope used; the error says the app named itself without its GUID. | | A script or service account asks for a scope with the app's own custom-domain URI | The scope was meant for another API but named the calling app. In one Microsoft Q&A thread a moderator found exactly that: *"the value in scope should be the client-id or application ID URI of your web API"*, not the caller's. | | A password-grant (ROPC) request through an identity broker such as Auth0 | The broker sends a resource or audience that resolves to its own Entra app. Reported in the Auth0 community. | None of these is a security signal. In the second row the app didn't mean to ask for itself at all, so check that first. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 90009 lands in, or whether it is logged at all. Our interpretation is that it may be rejected before a sign-in row is written, as a malformed request. Check your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "90009" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` If rows exist, which apps request tokens for themselves: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "90009" | summarize Rows = count(), Users = dcount(UserPrincipalName), Resources = make_set(ResourceIdentity, 5), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppId, AppDisplayName = coalesce(AppDisplayName, ServicePrincipalName) | sort by Rows desc ``` If nothing comes back, the error message the developer got is the evidence. It names the application ID. `ResultType` is a **string** column, so compare it with `"90009"`. ## How do I fix AADSTS90009? **For developers:** 1. Decide which API the token is really for. If it is a **different** API, put that API's identifier in the scope, for example `api:///.default` or `/.default`. Then add that API under your app's **API permissions** and get consent. 2. If your app really needs a token for **itself** (one registration for front end and API), give the resource as the GUID application ID, for example a scope of `/.default` or `/`. Microsoft notes that some APIs *"expect only the app ID (a GUID) and the scope name"* in the scope. 3. With the v1.0 endpoint or a library that sends `resource`, set `resource` to the client ID GUID, not the App ID URI. The Auth0 thread quotes a Stack Overflow answer with this advice; the poster didn't confirm it worked. 4. For app-only tokens, Microsoft's rule is that *"The scope to request for a client credential flow is the name of the resource followed by `/.default`"*. **For admins:** nothing to change in the tenant. Send the app ID from the error to the developer. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Restrictions on identifier URIs of Microsoft Entra applications](https://learn.microsoft.com/en-us/entra/identity-platform/identifier-uri-restrictions) 3. [servicePrincipal resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/serviceprincipal) 4. [Scopes for a web API accepting v1.0 tokens](https://learn.microsoft.com/en-us/entra/identity-platform/msal-v1-app-scopes) 5. [Acquire tokens to call a web API using a daemon application](https://learn.microsoft.com/en-us/entra/identity-platform/scenario-daemon-acquire-token) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 7. [Microsoft Q&A: OAuth 2.0 and Azure AD error AADSTS90009 (user report)](https://learn.microsoft.com/en-us/answers/questions/1076516/oauth-2-0-and-azure-active-directory-error-aadsts9) 8. [Microsoft Q&A: MSAL Python service account token error (user report)](https://learn.microsoft.com/en-us/answers/questions/764174/msal-python-service-account-token-genration-error) 9. [Auth0 Community: Azure AD integration with password grant returns error (user report)](https://community.auth0.com/t/azure-ad-integration-with-password-grant-returns-error/25103) ## Related codes [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS90009 fix: app requests a token for itself", https://brambrinkmeier.com/entra/aadsts/90009/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/90014/ # AADSTS90014 fix: required field missing from the request Canonical: https://brambrinkmeier.com/entra/aadsts/90014/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/90014.json **Short answer:** AADSTS90014 means Entra expected a field in the request or credential and it wasn't there. The message names the field: users report 'scope' from integrations such as ServiceNow, and 'request' when a browser app navigated back during sign-in. Microsoft gives no more detail. Low attack value. Read the field name and fix the request or the sign-in flow. **Fix:** Developer: read the field name in the error and add it. For 'scope' in a client credentials request, send `scope=/.default`. For 'request', make the app finish handling the sign-in response before it navigates. User: don't press Back during sign-in; start again from the app. | Field | Value | |---|---| | Code | AADSTS90014 | | Microsoft name | MissingRequiredField | | Category | App configuration | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS90014 mean? Microsoft's description: > **MissingRequiredField**: This error code might appear in various cases when an expected field isn't present in the credential. Entra ID expected a field and didn't find it. Microsoft doesn't list the cases, but the message names the field, and that is where to start. Users report two forms: - *"AADSTS90014: The required field 'scope' is missing from the credential"*, from ServiceNow using OAuth against a Microsoft API. - *"AADSTS90014: The required field 'request' is missing from the credential"*, from a single-page app signing in through Azure AD B2C, and quoted in a moderator's answer to a user signing in to school or work apps. Compare [900144](https://brambrinkmeier.com/entra/aadsts/900144/), which says *"The request body must contain the following parameter"* and also names what is missing. Microsoft doesn't explain when Entra returns one code and not the other. Either way the fix is to supply what the message names. If the message is about `resource` instead, see [901002](https://brambrinkmeier.com/entra/aadsts/901002/). ## Is it an attack? No documented attack pattern exists. The request is incomplete and no token is issued. | Pattern | Likely meaning | |---|---| | Field `scope`, from an integration or service account | A client credentials (or similar) token request without `scope`. Microsoft marks `scope` as **Required** in the client credentials flow. Configuration. | | Field `request`, from a browser app, now and then | In the B2C thread the accepted answer said it *"can be caused by navigating back after succesfuly loging-in"*, and the developer confirmed the app navigated back right after sign-in. Our reading: the sign-in response was lost because the app left the page before handling it. | | Field `request`, one user, a third-party app | The user pressed Back or reloaded during sign-in, or the app's flow has the same bug. Not an attack. | | 90014 from one app, starting right after a release | The new version stopped sending a field. | ## How do I find it in my logs (KQL)? Microsoft doesn't document whether or where 90014 is logged. Check all three sign-in tables: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "90014" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which app is missing which field. We assume `ResultDescription` carries the message with the field name filled in; we haven't seen a logged row: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "90014" | extend Field = extract(@"field '([^']+)'", 1, ResultDescription) | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppDisplayName, ServicePrincipalName, AppId, Field | sort by Rows desc ``` Apps that produced 90014 today but not in the previous 14 days. A `FirstSeen` right after a deployment points at the release: ```kusto let recent = union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "90014" | summarize Rows = count(), FirstSeen = min(TimeGenerated) by AppId, AppDisplayName; let before = union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated between (ago(15d) .. ago(1d)) | where ResultType == "90014" | distinct AppId; recent | join kind=leftanti before on AppId | sort by Rows desc ``` `ResultType` is a **string** column, so compare it with `"90014"`, not `90014`. In `AADServicePrincipalSignInLogs` the app name is in `ServicePrincipalName`, not `AppDisplayName`. ## How do I fix AADSTS90014? **For the user:** 1. Don't press Back or reload while the sign-in page is working. Close the tab and start again from the app. 2. If it keeps happening, clear the browser's cookies for the site and try again. That was the generic advice in the Q&A thread; one user said it didn't help. 3. Still failing: report it to IT with the full message, including the field name. **For developers:** 1. Read the field name in the error and add it. 2. `scope` in a client credentials request: send the API's identifier with `.default`, for example `https://graph.microsoft.com/.default`. Microsoft: *"All scopes included must be for a single resource."* 3. `request` in a browser app: let the app finish processing the sign-in response before it routes or navigates anywhere. The accepted answer in the B2C thread recommended a browser trace of the whole flow to see where it breaks. **For admins:** 1. Use the second query to find the app and the field, and send both to the app's owner. 2. For ServiceNow or another integration with an OAuth profile, check whether the profile sends a scope. ServiceNow documents the 'scope' form of this error in KB0866332. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and the OAuth 2.0 client credentials flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-client-creds-grant-flow) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 4. [How do I fix a AADSTS90014 error code? (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/1443443/how-do-i-fix-a-aadsts90014-error-code) 5. [AADSTS90014: The required field 'request' is missing (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/1161763/aadsts90014-the-required-field-request-is-missing) 6. [AADSTS90014: The required field 'scope' is missing from the credential (ServiceNow KB0866332)](https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0866332) ## Related codes [AADSTS900144](https://brambrinkmeier.com/entra/aadsts/900144/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS90023](https://brambrinkmeier.com/entra/aadsts/90023/), [AADSTS901002](https://brambrinkmeier.com/entra/aadsts/901002/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS90014 fix: required field missing from the request", https://brambrinkmeier.com/entra/aadsts/90014/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/90015/ # AADSTS90015 fix: sign-in request URL is too long Canonical: https://brambrinkmeier.com/entra/aadsts/90015/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/90015.json **Short answer:** AADSTS90015 means the sign-in request URL Entra received had a query string that was too long. Sign-in requests travel as URL parameters, so a large state value, a long return URL or a chain of identity providers can push it over the limit. Users report it from Jira Cloud for Outlook, Azure Databricks and chained Okta setups. Low attack value. **Fix:** User: open the app from its normal start URL, not a bookmark or deep link, clear cookies or use a private window, and try again. Developer: keep the request small. Put a short key in `state`, not a URL or app data, and shorten return URLs. Many users at once: it is likely on the app's side. | Field | Value | |---|---| | Code | AADSTS90015 | | Microsoft name | QueryStringTooLong | | Category | Graph request shape | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS90015 mean? Microsoft's description: > **QueryStringTooLong**: The query string is too long. The message users see is *"AADSTS90015: Requested query string is too long."* Sign-in requests to Entra ID are URLs. An OAuth 2.0 or OpenID Connect sign-in is a request to the `/authorize` endpoint with everything in the query string: `client_id`, `redirect_uri`, `scope`, `state` and more. A SAML sign-in works the same way: Microsoft's SAML reference says the app *"uses an HTTP Redirect binding to pass an `AuthnRequest`"* to Entra ID. If that URL gets too long, Entra ID rejects the request with 90015. Microsoft doesn't publish the limit. Atlassian's support article says Microsoft restricts query parameters *"to a maximum of 2048 characters"*; we haven't found that number in Microsoft's documentation. What makes a request long, in our reading: - **The `state` parameter.** Microsoft says it *"can be a string of any content that you wish"* and *"can also encode information about the user's state in the app"*. Apps that pack a lot into it make every sign-in URL longer. - **Long return or deep-link URLs**, carried inside `redirect_uri`, `state` or a SAML `RelayState`, and URL-encoded on top. - **Chained identity providers.** Each hop can wrap the previous request in its own. A user on the Okta forum reports the error only with Okta → Okta → Entra ID; single-hop setups worked. ## Is it an attack? No. It is a request Entra ID couldn't accept, not a failed credential check, and no token is issued. Users report it in these settings: | Pattern | Likely meaning | |---|---| | Many users of one SaaS app at once, starting on the same day | A change on the app vendor's side. In March 2026 Azure Databricks users in several tenants reported it; a Microsoft Q&A moderator called it a service-side issue, and Databricks fixed it on its side. | | One add-on or app, mostly when the user isn't signed in to it yet | The app's own sign-in flow builds a long URL. Atlassian documents this for Jira Cloud for Outlook. | | SAML through more than one identity provider | Chained redirects. Reported with Okta in front of Entra ID. | | One user, intermittently | Our interpretation: a bookmark or deep link with a long return URL. Try the app's normal start page. | ## How do I find it in my logs (KQL)? Microsoft doesn't document whether a 90015 is written to the sign-in logs. The request is rejected early, and we don't know whether a row is created. Check all three tables: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "90015" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` If rows exist, find the app, the protocol and the browser. `AuthenticationProtocol` tells SAML (`saml20`) from OAuth (`oAuth2`): ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "90015" | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), UserAgents = make_set(UserAgent, 5) by AppDisplayName, AppId, AuthenticationProtocol | sort by Users desc ``` Sudden spread across users of one app, the vendor-side pattern. Five users in an hour is a starting point: ```kusto SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "90015" | summarize Users = dcount(UserPrincipalName) by AppDisplayName, bin(TimeGenerated, 1h) | where Users >= 5 | sort by TimeGenerated desc ``` If the first query returns nothing while users do see the error, the request probably never produced a sign-in row. Then the browser is your only evidence: ask the user for the Request ID, Correlation ID and timestamp from the error page. ## How do I fix AADSTS90015? **For the user:** 1. Open the app from its normal start address, not from an old bookmark or a link deep inside the app. 2. Clear cookies for the site, or use a private window, and keep only one account signed in. These are the steps suggested to Databricks users while the vendor fix was pending. 3. Jira Cloud for Outlook: Atlassian's fix is to sign in to `id.atlassian.com` with Microsoft first, then connect the add-on from Outlook on the web, and then go back to the desktop app. 4. If it still fails, report it with the Request ID, Correlation ID and timestamp from the error page. **For developers:** 1. Keep `state` short. Microsoft: *"do not put URLs or other sensitive data directly in the state parameter. Instead, use a key or identifier that corresponds to data stored in browser storage"*. 2. Don't carry long deep-link URLs through the sign-in. Store the target and pass a short key. 3. Request only the scopes you need at sign-in. Every scope adds to the URL. 4. For chained identity providers, cut a hop if you can. Our reading is that each hop adds its own wrapped request. **For admins:** 1. Many users of one app at the same time points to the vendor. Check their status page or support before changing anything in your tenant. 2. For a home-built app, send the second query's result to the developer with the steps above. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow) 3. [Single sign-on SAML protocol](https://learn.microsoft.com/entra/identity-platform/single-sign-on-saml-protocol) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 5. [Jira Cloud for Outlook: AADSTS90015: Requested query string is too long (Atlassian)](https://support.atlassian.com/jira/kb/jira-cloud-for-outlook-aadsts90015-requested-query-string-is-too-long/) 6. [AADSTS90015 Requested query string is too long (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/5827320/aadsts90015-requested-query-string-is-too-long) 7. [AADSTS90015: Requested query string is too long (Okta developer forum)](https://devforum.okta.com/t/aadsts90015-requested-query-string-is-too-long/15905/5) ## Related codes [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS900144](https://brambrinkmeier.com/entra/aadsts/900144/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS90015 fix: sign-in request URL is too long", https://brambrinkmeier.com/entra/aadsts/90015/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/90019/ # AADSTS90019 fix: no tenant found in the sign-in request Canonical: https://brambrinkmeier.com/entra/aadsts/90019/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/90019.json **Short answer:** AADSTS90019 means Microsoft Entra ID couldn't work out which tenant a sign-in was for: the request didn't name one and the credentials didn't imply one. Users often see it in Outlook or the browser after typing a short username. Our reading: developers can hit it when an app uses the `common` endpoint with no user or tenant hint. It is a configuration or input error with low attack value. **Fix:** User: sign in with your full work email address ({user-principal-name}), not a short username, and retype saved credentials. Developer: put your tenant ID or verified domain in the authority URL, or send a `login_hint` or `domain_hint` when you use `common` or `organizations`. | Field | Value | |---|---| | Code | AADSTS90019 | | Microsoft name | MissingTenantRealm | | Category | Graph request shape | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS90019 mean? Microsoft's description: > **MissingTenantRealm**: Microsoft Entra ID was unable to determine the tenant identifier from the request. The message users post is longer: *"No tenant-identifying information found in either the request or implied by any provided credentials."* Entra ID didn't know which organisation's directory to use, so, our reading, it stopped before checking anything else. Entra ID gets the tenant from one of two places: - **The URL.** In the authority `https://login.microsoftonline.com//`, Microsoft says *"the `` in the URL is the tenant ID of the Microsoft Entra tenant (a GUID), or its tenant domain."* - **The user.** On the common sign-in page users *"enter a user principal name (UPN). Microsoft Entra ID uses this information to determine the correct sign-in location."* Microsoft calls this Home Realm Discovery. Our reading: 90019 is what you get when neither source gives an answer. The request went to `common` or `organizations`, and there was no username with a known domain, no hint, and no credential that points at a tenant. Don't confuse it with two codes that already have pages. [90002](https://brambrinkmeier.com/entra/aadsts/90002/) means a tenant value was sent but no such tenant exists. [900023](https://brambrinkmeier.com/entra/aadsts/900023/) means the tenant value isn't a valid tenant ID or domain at all. With 90019 there was no tenant value to check. ## Is it an attack? Rarely. Our reading: the request fails before any user, password or app in your tenant is looked at. Users report it in ordinary situations: - A university helpdesk sees it when students sign in to **Outlook**. Their advice is to enter the full email address, retype saved credentials, and try another browser or a private window. - TheWindowsClub reports it for Office 365 and Skype for Business sign-ins. - Quest has a knowledge base entry for it in Essentials for Office 365, a migration tool, which suggests admin tools and integrations hit it too. | Pattern | Likely meaning | |---|---| | One user, one app, then a success | The user typed a short username or a saved credential was wrong. Benign. | | Every run of a script or service fails | The script sends an app-only request to `common` or `organizations`. A developer error. | | A third-party federation or migration tool fails for everyone | The tool's tenant or domain setting is empty or wrong. Configuration. | Our reading: since Entra ID didn't find a tenant, it may not write the failure to your tenant's sign-in log at all. Microsoft doesn't document this. An empty result from the queries below doesn't prove users aren't hitting it; ask them for the error page details. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 90019 lands in, or whether it reaches a tenant's log at all. Check your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "90019" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` If rows exist, see which app, client and user agent produce them: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "90019" | summarize Rows = count(), Users = dcount(UserPrincipalName), Clients = make_set(ClientAppUsed, 5), Agents = make_set(UserAgent, 5), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppDisplayName, AppId | sort by Rows desc ``` `ResultType` is a **string** column, so compare it with `"90019"`, not `90019`. ## How do I fix AADSTS90019? **For the user:** 1. Sign in with your **full work email address** (for example `{user-principal-name}`), not just your username. Entra ID uses the domain part to find your organisation. 2. If a password manager or the app filled in the name, retype it yourself. 3. Users report that a private browser window, clearing the browser cache, or another browser also helps. If none of that works, send your IT helpdesk the error details. **For developers:** 1. If your app serves one organisation, put the tenant ID (GUID) or a verified domain in the authority: `https://login.microsoftonline.com//`. 2. For app-only requests (client credentials), the token request needs a tenant. Microsoft's reference marks `tenant` as **Required**: *"The directory tenant the application plans to operate against, in GUID or domain-name format."* 3. For a multitenant app on `common` or `organizations`, give Entra ID a way to find the tenant: a `login_hint` with the user's address, or a domain hint. Microsoft lists the domain hint per protocol: `domain_hint` for OpenID Connect, `whr` for WS-Federation, and a domain hint or `whr` for SAML. **For admins:** 1. For a third-party tool or federation service (a migration tool, a WS-Federation identity provider), check that its tenant or domain setting is filled in with your tenant ID or a verified domain. 2. Check that users' sign-in names use a domain verified in your tenant. Microsoft notes that sign-in uses *"organization and user settings for the username entered on the sign-in page."* ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Application configuration options (MSAL): Authority](https://learn.microsoft.com/en-us/entra/identity-platform/msal-client-application-configuration) 3. [Microsoft identity platform and the OAuth 2.0 client credentials flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-client-creds-grant-flow) 4. [Home Realm Discovery for an application](https://learn.microsoft.com/entra/identity/enterprise-apps/home-realm-discovery-policy) 5. [Username lookup during sign-in (sign-in realm discovery)](https://learn.microsoft.com/en-us/entra/identity/users/signin-realm-discovery) 6. [Receiving error code AADSTS90019 in Outlook (CCAC help center, user report)](https://helpcenter.ccac.edu/137393-outlook/receiving-error-code-aadsts90019-in-outlook) 7. [AADSTS90019: No tenant-identifying information found (TheWindowsClub, user report)](https://www.thewindowsclub.com/aadsts90019-no-tenant-identifying-information-found) 8. [AADSTS90019 (Quest Essentials for Office 365 KB 4230157, user report)](https://support.quest.com/ja-jp/kb/4230157/aadsts90019-no-tenant-identifying-information-found-in-either-the-request-or-implied-by-any-provided-credentials) ## Related codes [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS900023](https://brambrinkmeier.com/entra/aadsts/900023/), [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS90019 fix: no tenant found in the sign-in request", https://brambrinkmeier.com/entra/aadsts/90019/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/90023/ # AADSTS90023: Entra rejected the request as invalid (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/90023/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/90023.json **Short answer:** AADSTS90023 means Microsoft Entra ID rejected the token request as invalid. Microsoft's reference describes it only as InvalidRequest. The lab has returned it for two different causes with two different messages: a client_assertion_type that is not the JWT bearer URN, and a device code polled with a different client_id than the one that requested it. Read the message, not just the code. **Fix:** Read the message: the code covers more than one cause. Developer, assertion case: send `client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer`, URL-encoded once, with `client_assertion`. Device code case: poll `/token` with the same `client_id` that called `/devicecode`. | Field | Value | |---|---| | Code | AADSTS90023 | | Microsoft name | InvalidRequest | | Category | Credentials and lockout | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-31 | ## What does AADSTS90023 mean? Microsoft's description: > **InvalidRequest**: The authentication service request isn't valid. That is as much as the reference says, and 90023 is a bucket, not a single fault. It is the code Entra uses when it refuses to process a token request at all, and the lab has produced it from two unrelated causes on two different flows. The code is the same; only the message tells them apart: | Message returned | Cause | Flow | |---|---|---| | *"Unexpected client assertion type."* | `client_assertion_type` is not the JWT bearer URN | Client credentials | | *"ClientId passed in the request doesn't match the one in cache"* | A device code is polled with a different `client_id` than the one that requested it | Device code | Both are request-validation failures: something about the shape or the consistency of the request is wrong, so Entra rejects it before doing any real authentication work. Expect other causes to exist that we have not seen. Always read `ResultDescription`, or the `error_description` returned to the caller, before acting on a 90023. ### Cause 1: unexpected client assertion type > AADSTS90023: Unexpected client assertion type. An app that authenticates with a certificate or a federated credential sends two parameters instead of a secret: the assertion itself, and a parameter saying what kind of assertion it is. There is exactly one accepted value. Microsoft's certificate credentials page: | Parameter | Value | Microsoft's description | |---|---|---| | `client_assertion_type` | `urn:ietf:params:oauth:client-assertion-type:jwt-bearer` | This is a fixed value, indicating that you're using a certificate credential. | | `client_assertion` | `JWT` | This is the JWT created above. | The client credentials flow page repeats it: *"The value must be set to `urn:ietf:params:oauth:client-assertion-type:jwt-bearer`."* Anything else, including a shortened form, a URL-style variant or a double-encoded string, is "unexpected". Three codes sit close to this one, and the difference is how far the request got: | Code | Meaning | |---|---| | **90023** | The assertion *type* is not the accepted URN. Entra didn't get as far as reading the assertion. | | [50027](https://brambrinkmeier.com/entra/aadsts/50027/) | The type was accepted, but the assertion is not a well-formed JWT. | | **700027** | *"Client assertion failed signature validation"* in Microsoft's reference. A valid JWT, wrong signature. | | [7000216](https://brambrinkmeier.com/entra/aadsts/7000216/) | Nothing was sent at all on a `client_credentials` request. | ### Cause 2: device code polled with a different client ID > AADSTS90023: ClientId passed in the request doesn't match the one in cache The device code flow spans two requests. The app calls `/devicecode` with its `client_id` and gets a `device_code` back; it then polls `/token` with that `device_code`. Microsoft's [device authorization grant page](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-device-code) requires the second request to carry the same client: the `client_id` on the token request *"Must match the `client_id` used in the initial request."* The message says what the server is doing. The `device_code` is a handle to state Entra is holding ("the one in cache"), and the client ID that created that state is part of it. Poll with a different client ID and the handle no longer matches its owner, so the request is invalid. What this means in practice: the `device_code` is not a bearer token you can redeem from anywhere with anything. It is bound to the application that asked for it. | Code | When you get it in the device code flow | |---|---| | **90023** | Right `device_code`, wrong `client_id`. | | [70016](https://brambrinkmeier.com/entra/aadsts/70016/) | Right `device_code` and `client_id`, but nobody has signed in yet. Normal; keep polling. | | [7000014](https://brambrinkmeier.com/entra/aadsts/7000014/) | The `device_code` value itself isn't recognised. | Our reading: this check happens before the "has the user approved yet?" check, because the lab got 90023 rather than [70016](https://brambrinkmeier.com/entra/aadsts/70016/) for a code that was still outstanding. That ordering comes from one run. ## Reproduced in the lab Both causes were reproduced against a lab tenant. The frontmatter records the first one. ### Unexpected client assertion type (30 October 2026) On 30 October 2026 an automated lab run sent a client-credentials token request with a valid `client_assertion` but a `client_assertion_type` that Entra does not accept. Entra returned: > AADSTS90023: Unexpected client assertion type. Both rounds of the run returned the same code and the same one-line message, which is short enough that the lab's 160-character cut does not truncate it. The run had expected either 9002313 or 700027, so this is a case where guessing the code from the documentation would have been wrong. In the same run, a `client_assertion` that was not a JWT at all, sent with the correct assertion type, returned [50027](https://brambrinkmeier.com/entra/aadsts/50027/) instead, so the two checks run in that order: type first, then format. No sign-in log row was captured. See [how pages are checked](https://brambrinkmeier.com/methodology/). ### Device code redeemed with a different client ID (31 October 2026) On 31 October 2026 a later run requested a device code with one application's `client_id` and then polled the token endpoint for that same `device_code` with a different `client_id`. Entra returned: > AADSTS90023: ClientId passed in the request doesn't match the one in cache That run had expected 70016, 7000215 or 70002. It got none of them, which is the second time this code has turned up where the documentation gave no reason to expect it. Note the message has no trailing full stop, unlike the assertion-type message, so match on a substring rather than the whole line. No sign-in log row was captured for this case either, and the message mentions no application, user or tenant, so the attacker's view of it discloses nothing. ## Is it an attack? Usually not, in either case. A hand-built token request, or a library being driven in a way it wasn't designed for, is the normal cause. The accepted assertion type is long and easy to mistype or to encode twice, and the device code case needs two requests to disagree with each other. | Pattern | Likely meaning | |---|---| | A new integration fails on every attempt | The parameter is wrong in the code or the configuration. It has never worked. | | Started after a library or SDK upgrade | The request is now being assembled differently. Compare the parameters sent before and after. | | Appears alongside [50027](https://brambrinkmeier.com/entra/aadsts/50027/) and 700027 for one app | Someone is iterating on a client assertion implementation. Benign, and usually the app's own developer. | | For one app ID from an address you don't own | Someone else is constructing requests for your app ID. Nothing is disclosed by this error, but check whether the same address produced a success. | | The device code message, from a tool that worked yesterday | Two code paths in the tool now use different client IDs, or a config change replaced one of them. | | The device code message for an app you did not configure for device code flow | Someone is trying a `device_code` against a client ID that did not request it. It fails, but device code flow is [a phishing vector](https://brambrinkmeier.com/entra/aadsts/70016/) and the app's own device code traffic is worth reviewing. | ## How do I find it in my logs (KQL)? Which sign-in table 90023 lands in is undocumented, and the generic description means it can arrive from flows other than client assertions. Start wide and read the descriptions: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "90023" or ResultSignature == "90023" | summarize Rows = count(), LastSeen = max(TimeGenerated), Descriptions = make_set(ResultDescription, 10) by SourceTable ``` `ResultDescription` is documented as *"the error message or the reason for failure for the corresponding sign-in activity"* in `SigninLogs`, and as *"the error description for the sign-in operation"* in `AADServicePrincipalSignInLogs`. The set of descriptions is what tells you which cause your 90023 rows are, and whether there is a third one we have not documented. Split the two known causes apart. The device code case is a public client flow, so look for it in the user sign-in tables rather than the service principal one: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "90023" or ResultSignature == "90023" | extend Cause = case(ResultDescription has "assertion type", "client assertion type", ResultDescription has "doesn't match the one in cache", "device code client ID mismatch", "other or unknown") | summarize Rows = count(), LastSeen = max(TimeGenerated), Apps = make_set(AppId, 10) by SourceTable, Cause | sort by Rows desc ``` Rows landing in `other or unknown` are the interesting ones: a cause of 90023 neither of the lab runs produced. Narrow to the client assertion case per app: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "90023" or ResultSignature == "90023" | where ResultDescription has "assertion type" | summarize Failures = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), CredentialTypes = make_set(ClientCredentialType, 5), IPs = make_set(IPAddress, 10) by AppId, ServicePrincipalName | sort by Failures desc ``` The `has "assertion type"` filter assumes the message reaches the log. Confirm on one row before building an alert on it; if `ResultDescription` is empty in your workspace, drop that line and separate the cases another way. Counting all three assertion errors together is often more useful than any one of them, because a developer working on a certificate credential produces a mix: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType in ("90023", "50027", "700027") or ResultSignature in ("90023", "50027", "700027") | summarize Attempts = count(), LastSeen = max(TimeGenerated) by AppId, ServicePrincipalName, ResultType, ResultSignature | sort by Attempts desc ``` As a starting point, a burst over a few minutes for one app is a developer; a slow trickle for weeks is a job nobody has fixed. ## How do I fix AADSTS90023? Start by reading the message. The two known causes have nothing to do with each other. **For developers, "Unexpected client assertion type":** 1. Set `client_assertion_type` to exactly `urn:ietf:params:oauth:client-assertion-type:jwt-bearer`. Nothing else is accepted. 2. Check the encoding. The value is URL-encoded once as part of the form body. Encoding the colons twice produces a different string, and Entra sees an unexpected type. 3. Send `client_assertion` in the same request. The type parameter alone is not a credential. 4. Prefer a library over hand-built requests. MSAL sets both parameters for you when you configure a certificate credential. 5. If the error changes to [50027](https://brambrinkmeier.com/entra/aadsts/50027/), the type is now right and the assertion itself needs work: the header needs `alg`, `typ` and `x5t#S256`, and the claims need `aud`, `iss`, `sub`, `jti`, `nbf` and `exp`, as Microsoft's certificate credentials page sets out. **For developers, "ClientId passed in the request doesn't match the one in cache":** 1. Use one `client_id` for the whole device code flow. The token request must carry the same client ID as the `/devicecode` request that produced the `device_code`. 2. Check for two configurations in one process: a hard-coded default client ID in one code path and a configured one in the other is the usual way the two requests drift apart. 3. Keep the `device_code` with the client ID that obtained it. Do not cache or pass device codes between applications; the binding is enforced. 4. Keep the authority the same across both requests too. A tenant mismatch produces [50059](https://brambrinkmeier.com/entra/aadsts/50059/) or [90133](https://brambrinkmeier.com/entra/aadsts/90133/) rather than 90023. 5. Once both requests agree, expect [70016](https://brambrinkmeier.com/entra/aadsts/70016/) until the user signs in. That is the normal reply, not an error. **For admins:** 1. Nothing to change in the tenant. This is the shape of the request, not a setting on the app or a policy. 2. Use the queries above to find which app and which owner, and pass them Microsoft's certificate credentials page, or its device code page for the device code case. 3. If the device code message appears for apps you do not expect to use the flow, review device code flow in the tenant: see [70016](https://brambrinkmeier.com/entra/aadsts/70016/) for the inventory query and the Conditional Access control. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Client-credentials token request against a lab tenant; scenario: Unknown client_assertion_type). First line returned: > AADSTS90023: Unexpected client assertion type. Lab-run rows naming this code (9; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-30 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-30 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-30 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-30 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-31 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-31 | Device code redeemed with a different client ID | 70016 / 7000215 / 70002 | 90023 | AADSTS90023: ClientId passed in the request doesn't match the one in cache | | 2026-10-31 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-31 | Device code redeemed with a different client ID | 70016 / 7000215 / 70002 | 90023 | AADSTS90023: ClientId passed in the request doesn't match the one in cache | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform application authentication certificate credentials](https://learn.microsoft.com/en-us/entra/identity-platform/certificate-credentials) 3. [Microsoft identity platform and the OAuth 2.0 client credentials flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow) 4. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) 5. [Microsoft identity platform and the OAuth 2.0 device authorization grant flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-device-code) ## Related codes [AADSTS50027](https://brambrinkmeier.com/entra/aadsts/50027/), [AADSTS700024](https://brambrinkmeier.com/entra/aadsts/700024/), [AADSTS7000216](https://brambrinkmeier.com/entra/aadsts/7000216/), [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS70016](https://brambrinkmeier.com/entra/aadsts/70016/), [AADSTS7000014](https://brambrinkmeier.com/entra/aadsts/7000014/), [AADSTS50013](https://brambrinkmeier.com/entra/aadsts/50013/), [AADSTS90014](https://brambrinkmeier.com/entra/aadsts/90014/), [AADSTS900561](https://brambrinkmeier.com/entra/aadsts/900561/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS90023: Entra rejected the request as invalid (fix)", https://brambrinkmeier.com/entra/aadsts/90023/ (CC BY 4.0), last updated 2026-10-31. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/90072/ # AADSTS90072: External account doesn't exist in the tenant, MFA can't be satisfied Canonical: https://brambrinkmeier.com/entra/aadsts/90072/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/90072.json **Short answer:** AADSTS90072 means a user signed in with an external account that doesn't exist in the tenant they tried to reach, so they can't satisfy that tenant's MFA. It also appears for synced users when the ImmutableID (sourceAnchor) in Active Directory and Microsoft Entra ID don't match. It is a B2B or sync configuration problem with low attack value. **Fix:** Admin, B2B case: invite the user as a guest in the resource tenant, using the address they sign in with. Admin, synced user: make the ImmutableID in Entra ID match the sourceAnchor in Active Directory, then sync. User: sign in with your account for that tenant, or ask your contact to invite you. | Field | Value | |---|---| | Code | AADSTS90072 | | Microsoft name | PassThroughUserMfaError | | Category | Guests and tenants | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-24 | ## What does AADSTS90072 mean? Microsoft's description: > **PassThroughUserMfaError**: The external account that the user signs in with doesn't exist on the tenant that they signed into; so the user can't satisfy the MFA requirements for the tenant. This error also might occur if the users are synced, but there is a mismatch in the ImmutableID (sourceAnchor) attribute between Active Directory and Microsoft Entra ID. The account must be added as an external user in the tenant first. Sign out and sign in with a different Microsoft Entra user account. In plain terms, the user authenticated somewhere, but the tenant they are trying to reach has no matching account for them. Without an account there, that tenant can't run its MFA for them, so the sign-in stops. Microsoft names two causes: 1. **B2B:** an external account that was never added (invited) to the resource tenant. 2. **Directory sync:** a synced user whose ImmutableID (sourceAnchor) in on-premises Active Directory doesn't match the one in Microsoft Entra ID. It is close to [50020](https://brambrinkmeier.com/entra/aadsts/50020/), which also means an outside account isn't in the tenant. Microsoft's description of 90072 adds the MFA angle and the sync cause. ## Is it an attack? No. Both documented causes are configuration problems. | Pattern | Likely meaning | |---|---| | A partner user, first time on one of your apps | Not invited as a guest yet, or the invitation went to a different address. Benign. | | Your own staff signing in to a partner tenant | Same cause on the partner's side. They need to invite your user. Not your incident. | | One or a few of your own synced users, starting after an AD change or a sync server rebuild | ImmutableID / sourceAnchor mismatch. A sync problem to fix, not an attack. | | Many different external identities you never invited | Our interpretation, not a Microsoft statement: someone sending outside accounts at your apps. Same reading as the probing row on [50020](https://brambrinkmeier.com/entra/aadsts/50020/). Investigate the source. | The third row is the one that needs real work. An ImmutableID mismatch means on-premises and cloud no longer agree which object is which user, and the affected users can't sign in until it is fixed. ## How do I find it in my logs (KQL)? Who hits 90072, against which apps, and whether they are guests or members: ```kusto SigninLogs | where TimeGenerated > ago(14d) | where ResultType == "90072" | summarize Attempts = count(), Apps = make_set(AppDisplayName, 10), IPs = make_set(IPAddress, 10), HomeTenants = make_set(HomeTenantId, 5), UserTypes = make_set(UserType, 2), CrossTenant = make_set(CrossTenantAccessType, 5), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by UserPrincipalName | sort by Attempts desc ``` Split the B2B case from the sync case. Rows where the home tenant is your own tenant point to the sync cause; rows from other home tenants point to B2B: ```kusto SigninLogs | where TimeGenerated > ago(14d) | where ResultType == "90072" | extend Case = iff(HomeTenantId == ResourceTenantId, "own tenant (check sync)", "external (check B2B)") | summarize Users = dcount(UserPrincipalName), Attempts = count() by Case, AppDisplayName | sort by Attempts desc ``` That split is our reasoning from the two causes Microsoft lists, not a documented field mapping. Look at one row of each kind in your workspace to see how `HomeTenantId`, `UserType` and `UserPrincipalName` are filled for an account that doesn't exist in the tenant. They may be empty or show the identity from the other side. ## How does Conditional Access affect it? - The error is about MFA, but it isn't a Conditional Access block. The tenant has no account for the user, so there is no user object for your MFA policy to work with. - Once the external user is invited, your guest policies decide how they do MFA. Microsoft: *"If MFA trust is enabled, Microsoft Entra ID checks the user's authentication session for a claim indicating that MFA was fulfilled in the user's home tenant."* *"If MFA trust is disabled, the resource tenant presents the user with a challenge to complete MFA in the resource tenant."* - Microsoft advises: *"Before you create the Conditional Access policy, check your cross-tenant access settings to make sure your inbound MFA trust settings are configured as intended."* ## How do I fix AADSTS90072? **For the user:** sign out and sign in again with the account your organisation gave you for that tenant. If you are a partner, ask your contact to invite you as a guest. **For admins, B2B case:** 1. Invite the user as a guest (external user) in the resource tenant, using the address they actually sign in with. 2. Check your cross-tenant access settings for that partner, including inbound MFA trust, so the user knows where they will do MFA. **For admins, sync case:** 1. Compare the user's ImmutableID in Microsoft Entra ID with the sourceAnchor value in on-premises Active Directory. Microsoft names a mismatch in that attribute as the cause. 2. Fix the mapping so both sides refer to the same object, then run a sync and test the sign-in. Our advice, not a Microsoft procedure for this code: find out why the mismatch happened (a re-created AD account, a rebuilt sync server, a changed sourceAnchor attribute) before fixing users one by one. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Require multifactor authentication strength for external users (Conditional Access)](https://learn.microsoft.com/en-us/entra/identity/conditional-access/policy-guests-mfa-strength) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS50079](https://brambrinkmeier.com/entra/aadsts/50079/), [AADSTS16000](https://brambrinkmeier.com/entra/aadsts/16000/), [AADSTS51004](https://brambrinkmeier.com/entra/aadsts/51004/), [AADSTS500021](https://brambrinkmeier.com/entra/aadsts/500021/), [AADSTS500200](https://brambrinkmeier.com/entra/aadsts/500200/), [AADSTS500571](https://brambrinkmeier.com/entra/aadsts/500571/), [AADSTS5000211](https://brambrinkmeier.com/entra/aadsts/5000211/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS90072: External account doesn't exist in the tenant, MFA can't be satisfied", https://brambrinkmeier.com/entra/aadsts/90072/ (CC BY 4.0), last updated 2026-10-24. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/90094/ # AADSTS90094: "Need admin approval" screen (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/90094/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/90094.json **Short answer:** AADSTS90094 means a user tried to consent to an app, but the permissions it asks for need an administrator. Your user-consent restriction is holding. Usually it is a legitimate new app. The security signal is an unfamiliar app hitting 90094 for several users, which fits a consent-phishing attempt. Hunt it in SigninLogs by AppId. **Fix:** User: ask your IT team to review the app; don't try other accounts. Admin: check the app's publisher and requested permissions. If it is legitimate, grant admin consent for only the permissions it needs. If it looks like phishing, warn the users and check for consents that went through. | Field | Value | |---|---| | Code | AADSTS90094 | | Microsoft name | AdminConsentRequired | | Category | Consent and app permissions | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1566.002](https://attack.mitre.org/techniques/T1566/002/) Phishing: Spearphishing Link, [T1528](https://attack.mitre.org/techniques/T1528/) Steal Application Access Token | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS90094 mean? Microsoft's description: > **AdminConsentRequired**: Administrator consent is required. **On screen, this is the "Need admin approval" dialog.** Microsoft's guidance on permissions that need admin consent names it as the default experience, shown *"when your app requests a permission that requires admin consent"*. If your users are reporting "Need admin approval", this is the code behind it. The user reached a consent prompt for an app, and the permissions requested are ones your tenant doesn't let users grant themselves. The user is stopped until an admin consents. If your tenant has the admin consent workflow turned on, the user sees a different screen, **"Approval required"**, with a box to enter a justification and a **Request approval** button. That screen is [90095](https://brambrinkmeier.com/entra/aadsts/90095/), not this code. ## Is it an attack? The code itself means a control worked. Whether there is an attack behind it depends on the app. Microsoft's illicit-consent guidance describes the attack: an attacker registers an app, tricks a user into consenting, and then *"has account-level access to data without the need for an organizational account"*. The full quote and the investigation are on the [65001 page](https://brambrinkmeier.com/entra/aadsts/65001/) and in the [consent phishing guide](https://brambrinkmeier.com/guides/investigate-consent-phishing-entra-id/). Each 90094 is a user who reached a consent prompt and was stopped. That makes it a data point for consent-phishing attempts: | Pattern | Likely meaning | |---|---| | One or two users, a well-known SaaS app your company is adopting | A legitimate app waiting for admin review. Benign. | | Many users, one unfamiliar app, within hours | Users were sent a link to that app. That is the shape of a consent-phishing campaign. Look up the app and its publisher. | | An app name that imitates a Microsoft or internal tool, from an unverified publisher | Treat as phishing until shown otherwise. | | 90094 for an app, then a "Consent to application" audit event for the same app | Someone with admin rights consented. Confirm that was a deliberate review. | This reading is built on Microsoft's attack description, not on a Microsoft detection rule. ## How do I find it in my logs (KQL)? Which apps users are being stopped on: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "90094" | summarize Users = dcount(UserPrincipalName), Attempts = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), SampleUsers = make_set(UserPrincipalName, 10), IPs = make_set(IPAddress, 10) by AppId, AppDisplayName | sort by Users desc ``` An app with several users in a short window and no business owner is the one to look at first. Did anyone grant consent anyway? Microsoft's guidance is to search the **Microsoft Purview (unified) audit log** for **"Consent to application"** and check `IsAdminConsent`. The Entra audit log records the same operation; in Log Analytics: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where OperationName == "Consent to application" | extend Actor = tostring(InitiatedBy.user.userPrincipalName), AppName = tostring(TargetResources[0].displayName), AppObjectId = tostring(TargetResources[0].id), ConsentDetails = TargetResources[0].modifiedProperties | project TimeGenerated, Actor, AppName, AppObjectId, Result, ConsentDetails | sort by TimeGenerated desc ``` Compare `AppName` with the apps from the first query. The admin-consent flag sits inside `ConsentDetails` as the property named `ConsentContext.IsAdminConsent` (the granted permissions are in `ConsentAction.Permissions`). Field paths inside `InitiatedBy` and `TargetResources` vary; check them against a real event in your workspace. Note that the audit log identifies the app by its service principal object, while sign-in logs use `AppId`, so match on name or look up the IDs. `ResultType` is a **string** column, so compare it with `"90094"`, not `90094`. ## How do Conditional Access and MFA affect it? - 90094 isn't a Conditional Access result. It comes from your consent settings. - MFA doesn't help against consent phishing once consent is granted. Microsoft says password resets and MFA *"aren't effective against this type of attack"*. The consent restriction that produced this 90094 is the control that matters. - Recommended posture: restrict user consent and turn on the **admin consent workflow**. Users then get [90095](https://brambrinkmeier.com/entra/aadsts/90095/) and a request goes to reviewers, instead of a dead end that pushes them to find another way. ## How do I fix AADSTS90094? **For the user:** ask your IT team to review the app. Don't try other accounts to get past the prompt. **For admins:** 1. Look up the app from the first query: publisher, requested permissions, and whether anyone in the business asked for it. 2. If it is legitimate, grant admin consent for the permissions it needs, and no more. 3. If it looks like phishing, warn the users who hit it and check the audit query for any consent that did go through. 4. Enable the admin consent workflow so future requests reach a reviewer as 90095. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Request permissions that require administrative consent (Microsoft Learn)](https://learn.microsoft.com/en-us/security/zero-trust/develop/permissions-require-admin-consent) 2. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 3. [Detect and remediate illicit consent grants](https://learn.microsoft.com/en-us/defender-office-365/detect-and-remediate-illicit-consent-grants) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS90095](https://brambrinkmeier.com/entra/aadsts/90095/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS65004](https://brambrinkmeier.com/entra/aadsts/65004/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS65002](https://brambrinkmeier.com/entra/aadsts/65002/), [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/), [AADSTS1003031](https://brambrinkmeier.com/entra/aadsts/1003031/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS90094: "Need admin approval" screen (fix)", https://brambrinkmeier.com/entra/aadsts/90094/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/90095/ # AADSTS90095: "Approval required" screen (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/90095/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/90095.json **Short answer:** AADSTS90095 is an interrupt: a user hit a consent prompt for permissions that need an admin, and because the admin consent workflow is on, they are told to request approval. This is the recommended setup. The review queue becomes your consent-phishing triage queue. Hunt unfamiliar apps in SigninLogs with ResultType == "90095". **Fix:** User: send the admin consent request with a short reason, then wait for the reviewer. Reviewer: check the app's publisher, requested permissions and business need before approving, and grant only what it needs. If several users request the same unfamiliar app at once, deny it and warn them. | Field | Value | |---|---| | Code | AADSTS90095 | | Microsoft name | AdminConsentRequiredRequestAccess | | Category | Consent and app permissions | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Low: usually configuration or user error | | MITRE ATT&CK | [T1566.002](https://attack.mitre.org/techniques/T1566/002/) Phishing: Spearphishing Link, [T1528](https://attack.mitre.org/techniques/T1528/) Steal Application Access Token | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS90095 mean? Microsoft's description: > **AdminConsentRequiredRequestAccess**: In the Admin Consent Workflow experience, an interrupt that appears when the user is told they need to ask the admin for consent. **On screen, this is the "Approval required" dialog**, with a box to *"Enter justification for requesting this app"* and a **Request approval** button. Microsoft's guidance says it replaces the default screen once an admin turns on *Users can request admin consent to apps they're unable to consent to*. This is the same situation as [90094](https://brambrinkmeier.com/entra/aadsts/90094/), a user needing admin consent, but in a tenant where the admin consent workflow is enabled. Instead of a dead end, the user can send a request to the reviewers you designated. Without the workflow, the user gets the **"Need admin approval"** screen instead, which is 90094. ## Is it an attack? The code is an expected step, not a failure. It means your consent controls are set up the way you want them. The security work is in **what the requests are for**. Microsoft's illicit-consent guidance describes the attack: an attacker registers an app, tricks a user into consenting, and then *"has account-level access to data without the need for an organizational account"*. The full quote and the investigation are on the [65001 page](https://brambrinkmeier.com/entra/aadsts/65001/) and in the [consent phishing guide](https://brambrinkmeier.com/guides/investigate-consent-phishing-entra-id/). With the workflow on, an attacker's link ends at a 90095 and a request in your queue. The risk moves to the reviewer: if a reviewer approves a malicious app, the attack succeeds with admin consent. | Pattern | Likely meaning | |---|---| | One user, a known SaaS tool | A normal access request. Review it on its merits. | | Many users, the same unfamiliar app, in a short window | A link to that app went round, possibly by phishing. Treat the request as suspicious until the app is vetted. | | An app name imitating a Microsoft or internal tool | Treat as phishing until shown otherwise. Don't approve. | This reading is built on Microsoft's attack description, not on a Microsoft detection rule. ## How do I find it in my logs (KQL)? Which apps users are requesting, and how many users each: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "90095" | summarize Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), SampleUsers = make_set(UserPrincipalName, 10), IPs = make_set(IPAddress, 10) by AppId, AppDisplayName | sort by Users desc ``` Did a reviewer approve one of them? Microsoft's guidance is to search the **Microsoft Purview (unified) audit log** for **"Consent to application"** and check `IsAdminConsent`. The Entra audit log records the same operation; in Log Analytics: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where OperationName == "Consent to application" | extend Actor = tostring(InitiatedBy.user.userPrincipalName), AppName = tostring(TargetResources[0].displayName), AppObjectId = tostring(TargetResources[0].id), ConsentDetails = TargetResources[0].modifiedProperties | project TimeGenerated, Actor, AppName, AppObjectId, Result, ConsentDetails | sort by TimeGenerated desc ``` The admin-consent flag sits inside `ConsentDetails` as the property named `ConsentContext.IsAdminConsent` (the granted permissions are in `ConsentAction.Permissions`). Field paths inside `InitiatedBy` and `TargetResources` vary; check them against a real event in your workspace before alerting on them. `ResultType` is a **string** column, so compare it with `"90095"`, not `90095`. ## How do Conditional Access and MFA affect it? - 90095 isn't a Conditional Access result. It comes from your consent settings and the admin consent workflow. - MFA doesn't protect against an app that has been granted consent. Microsoft says password resets and MFA *"aren't effective against this type of attack"*. The review step is the control. ## How do I fix AADSTS90095? **For the user:** send the request with a short reason, then wait for the reviewer. **For admins and reviewers:** 1. Before approving, check the app's publisher, the permissions requested, and whether someone in the business actually needs it. 2. Grant only the permissions the app needs. 3. If several users requested the same unfamiliar app at once, treat it as a possible phishing campaign: deny, warn the users, and look for the delivery message. 4. Keep this setup. Restricted user consent plus the admin consent workflow is the recommended posture. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Request permissions that require administrative consent (Microsoft Learn)](https://learn.microsoft.com/en-us/security/zero-trust/develop/permissions-require-admin-consent) 2. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 3. [Detect and remediate illicit consent grants](https://learn.microsoft.com/en-us/defender-office-365/detect-and-remediate-illicit-consent-grants) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS90094](https://brambrinkmeier.com/entra/aadsts/90094/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS65004](https://brambrinkmeier.com/entra/aadsts/65004/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS90095: "Approval required" screen (fix)", https://brambrinkmeier.com/entra/aadsts/90095/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/90133/ # AADSTS90133: Device code flow not supported on /common or /consumers (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/90133/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/90133.json **Short answer:** AADSTS90133 means a device code request went to the /common or /consumers endpoint, where Entra didn't support it for that app. Microsoft doesn't list the code, but a code comment in its device code docs gives the message and the fix: use a tenant-specific authority. It is a configuration error with low attack value. **Fix:** Developer: use a tenant-specific authority for device code flow (https://login.microsoftonline.com/), not /common or /consumers, and use the same value for the devicecode and token requests. User: ask whoever runs the tool to set your tenant ID. | Field | Value | |---|---| | Code | AADSTS90133 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS90133 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS90133 (checked 30 October 2026). The nearest listed code is AADSTS90130: *"The application isn't supported over the /common or /consumers endpoints."* Microsoft does mention 90133 elsewhere. The .NET sample in its [device code flow article for desktop apps](https://learn.microsoft.com/entra/identity-platform/scenario-desktop-acquire-token-device-code-flow) lists it in a code comment, with the fix: ```csharp // AADSTS90133: Device Code flow is not supported under /common or /consumers endpoint. // Mitigation: as explained in the message from Azure AD, the authority needs to be tenanted ``` "Tenanted" means the sign-in URL names your tenant, by ID or domain, instead of `common` or `consumers`. The same sample uses `https://login.microsoftonline.com/contoso.com` as its authority. This is a code comment, not a reference entry. Microsoft's device code protocol page says something broader. It says the `{tenant}` value *"Can be `/common`, `/consumers`, or `/organizations`"*, or a tenant ID or domain. Our reading: the two pages don't contradict each other if 90133 applies only to some apps, but Microsoft doesn't say which ones. Treat the code comment as the documented trigger and the exact conditions as unknown. We tried to reproduce it on 30 October 2026. A lab run requested a device code on `/consumers` with an app registered for work accounts only. Entra didn't return 90133. It returned [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) instead: > AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. Our reading: on `/consumers` Entra looked for the app in a directory that isn't our lab tenant and didn't find it. In that one run, 700016 came back before any 90133 check. We haven't found the setup that returns 90133. See [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? No. Microsoft's comment points to a configuration error in the app or script that starts the device code flow. The device code request is the first step of the flow, before any user signs in. | Pattern | Likely meaning | |---|---| | A new CLI tool or script fails on its first run | The authority is `/common` or `/consumers`. Use your tenant ID or domain. | | A tool works for one tenant and fails after a config change | Someone replaced the tenant ID with a generic endpoint. Likely, but unconfirmed. | | A vendor tool fails for every customer | The vendor's default authority is generic. Ask for a tenant setting. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 90133 is logged in. Probably no row is written in your tenant: the request fails before a user signs in, and `/common` and `/consumers` don't name your tenant. Check anyway; this query is expected to return nothing: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "90133" | summarize Rows = count() by SourceTable ``` ## How do I fix AADSTS90133? **For the user:** you can't fix this. Tell whoever runs the tool that its sign-in setting needs your tenant ID. **For developers:** 1. Use a tenant-specific authority for device code flow, as Microsoft's comment says: `https://login.microsoftonline.com/`. 2. Use the same value for the device code request (`/oauth2/v2.0/devicecode`) and the token polling request (`/oauth2/v2.0/token`). Microsoft's protocol page says the polling request must use *"the same tenant or tenant alias used in the initial request."* 3. If the tool serves many tenants, make the tenant a setting instead of hard-coding `common`. **For admins:** give the tool your tenant ID. Our [AADSTS90002 page](https://brambrinkmeier.com/entra/aadsts/90002/) shows how to find it. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. Lab-run rows naming this code (22; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-31 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-31 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-31 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Desktop app that calls web APIs: Acquire a token by using device code flow](https://learn.microsoft.com/entra/identity-platform/scenario-desktop-acquire-token-device-code-flow) 3. [Microsoft identity platform and the OAuth 2.0 device authorization grant flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-device-code) ## Related codes [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS50194](https://brambrinkmeier.com/entra/aadsts/50194/), [AADSTS70016](https://brambrinkmeier.com/entra/aadsts/70016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS90133: Device code flow not supported on /common or /consumers (fix)", https://brambrinkmeier.com/entra/aadsts/90133/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/135011/ # AADSTS135011: Device used during authentication is disabled Canonical: https://brambrinkmeier.com/entra/aadsts/135011/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/135011.json **Short answer:** AADSTS135011 means the device used for the sign-in is disabled in Microsoft Entra ID. Usually an admin disabled it during cleanup or incident response, and something on that device still tries to get tokens. After an incident, these rows show where the quarantined device is and when it reconnects. **Fix:** Admin: check the audit log for who disabled the device. If it was disabled during incident response, leave it disabled. If it was a mistake, re-enable it with Update-MgDevice -AccountEnabled:$true. If the device is gone, delete it and register a new one. User: contact IT. | Field | Value | |---|---| | Code | AADSTS135011 | | Microsoft name | Device disabled | | Category | Devices | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS135011 mean? Microsoft's description: > Device used during the authentication is disabled. Microsoft's reference table gives no PascalCase name for this code. The device object in Entra ID has its account disabled, so Entra ID won't use it for authentication. ## Is it an attack? The code itself is not an attack. It is the result of an admin action. The question is **why the device was disabled and what is still trying to use it.** | Pattern | Likely meaning | |---|---| | Device disabled during stale-device cleanup, user still has it | Benign. The user is on a device you retired. | | Device disabled during incident response, then 135011 rows appear | **The quarantined device is back online and trying to get tokens.** Note the IP, time and app. | | 135011 from an IP or country the user never uses | Possible attacker-held device or replayed device-bound session. Investigate (reasoning, not a Microsoft statement). | | Many users failing with 135011 at once | Bulk disable by a script or policy. Check the audit log for who disabled them. | Microsoft's own revoke-access procedure disables the user's devices as one of its steps: ```powershell Update-MgDevice -DeviceId $Device.Id -AccountEnabled:$false ``` So in an incident, 135011 is often the expected aftermath of that step. Its value is forensic: each row tells you when and from where the disabled device reconnected. ## How do I find it in my logs (KQL)? Every disabled device still attempting sign-ins, with where it came from: ```kusto union (SigninLogs | where TimeGenerated > ago(14d) | where ResultType == "135011" | extend DeviceId = tostring(DeviceDetail.deviceId), DeviceName = tostring(DeviceDetail.displayName), Country = tostring(LocationDetails.countryOrRegion), Log = "Interactive"), (AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(14d) | where ResultType == "135011" | extend DeviceId = tostring(parse_json(DeviceDetail).deviceId), DeviceName = tostring(parse_json(DeviceDetail).displayName), Country = tostring(parse_json(LocationDetails).countryOrRegion), Log = "NonInteractive") | summarize Attempts = count(), IPs = make_set(IPAddress, 10), Countries = make_set(Country, 5), Apps = make_set(AppDisplayName, 5), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Logs = make_set(Log) by UserPrincipalName, DeviceId, DeviceName | sort by LastSeen desc ``` Focus on one incident: the device you disabled, after the time you disabled it. ```kusto let incidentDevice = ""; // the device ID (deviceId), not the object ID let disabledAt = datetime(2026-10-01T09:00:00Z); union (SigninLogs | where TimeGenerated > disabledAt | extend DeviceId = tostring(DeviceDetail.deviceId)), (AADNonInteractiveUserSignInLogs | where TimeGenerated > disabledAt | extend DeviceId = tostring(parse_json(DeviceDetail).deviceId)) | where DeviceId == incidentDevice | project TimeGenerated, UserPrincipalName, ResultType, IPAddress, AppDisplayName, ClientAppUsed, UserAgent | sort by TimeGenerated asc ``` `DeviceDetail` is **dynamic** in `SigninLogs` and **string** in `AADNonInteractiveUserSignInLogs`, so each leg of the union extracts the device ID its own way before the tables are combined. The property names follow the Microsoft Graph `signIn` device detail object; check them against a row in your own workspace first. Which log 135011 lands in is reasoned from the mechanism, not measured: a device-based SSO refresh is non-interactive, a fresh sign-in is interactive. The first query searches both. ## How does Conditional Access affect it? - 135011 is not a Conditional Access result code. It reports the state of the device object itself. - Disabling the device removes it as an option for policies that require a compliant or hybrid joined device. If the user's only managed device is disabled, they will start hitting 53000 or 53001 from whatever device they use next. - Microsoft's revoke-access procedure treats disabling devices and revoking the user's refresh tokens (`Revoke-MgUserSignInSession`) as separate steps. Do both. By default, Microsoft assigns access tokens a lifetime of 60 to 90 minutes, so already-issued access tokens can keep working until they expire, unless Continuous Access Evaluation applies (Exchange, SharePoint and Teams through CAE-capable clients), where Microsoft says revocation is enforced with *"latency of up to 15 minutes"*. The [session revocation guide](https://brambrinkmeier.com/guides/revoke-sessions-and-verify-entra-id/) has the detail. ## How do I fix AADSTS135011? **For the user:** contact IT. The device has been disabled on purpose or by cleanup, and you can't re-enable it yourself. **For admins:** 1. Check the Entra audit log for who disabled the device and when. 2. If it was disabled during incident response, leave it disabled. Record each 135011 row (IP, time, app) as evidence of where the device is. 3. If it was a mistake or a stale-device cleanup that hit a device still in use, re-enable it: ```powershell Update-MgDevice -DeviceId $Device.Id -AccountEnabled:$true ``` 4. If the device is gone for good, delete the device object and have the user register a new device. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Access tokens in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens) 2. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 3. [Revoke user access in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/users/users-revoke-access) 4. [Continuous access evaluation](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-continuous-access-evaluation) 5. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 6. [signIn resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/signin) 7. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50173](https://brambrinkmeier.com/entra/aadsts/50173/), [AADSTS50057](https://brambrinkmeier.com/entra/aadsts/50057/), [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS53001](https://brambrinkmeier.com/entra/aadsts/53001/), [AADSTS50097](https://brambrinkmeier.com/entra/aadsts/50097/), [AADSTS50155](https://brambrinkmeier.com/entra/aadsts/50155/), [AADSTS700003](https://brambrinkmeier.com/entra/aadsts/700003/), [AADSTS5000611](https://brambrinkmeier.com/entra/aadsts/5000611/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS135011: Device used during authentication is disabled", https://brambrinkmeier.com/entra/aadsts/135011/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/165000/ # AADSTS165000: User session context is missing (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/165000/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/165000.json **Short answer:** AADSTS165000 means the browser lost or didn't send the cookies, form fields or headers that keep one sign-in together, so the sign-in page stops. Microsoft's error reference doesn't list it. Users report it on iPads, a Mac and in Edge. Two users fixed it on iPads by setting the device clock to automatic. Low attack value. **Fix:** User: set the device date and time to automatic with the right time zone (two users report this fixed it on iPads). Then allow cookies, avoid private browsing for the sign-in, or try another browser. Admin: ask which device and browser, and check the clock first. | Field | Value | |---|---| | Code | AADSTS165000 | | Category | Tokens and sessions | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS165000 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS165000 (checked 30 October 2026). We found no Microsoft documentation page for it. The wording comes from user reports on Microsoft Q&A. The common part of the message is: > AADSTS165000: Invalid Request: … One or more of the user context values (cookies; form fields; headers) were not supplied, every request must include these values and maintain them across a complete single user flow. The first part and the ending vary. Three threads show three versions: | Thread | Text after "Invalid Request:" and at the end | |---|---| | [iPads, school tenant](https://learn.microsoft.com/en-us/answers/questions/2264720/two-of-our-users-are-getting-the-aadsts165000-erro) | *"The user session context is missing."* | | [Mac, Microsoft 365 Home](https://learn.microsoft.com/en-us/answers/questions/5643859/aadsts165000-invalid-request-the-user-session-cont) | *"The user session context is missing."* … *"Failure Reasons:[Missing session context cookie;]"* | | [Edge, Azure Site Recovery appliance](https://learn.microsoft.com/en-us/answers/questions/1691539/azure-site-recovery-configuration-gives-aadsts1650) | *"The request did not include the required tokens for the user context."* … *"The request did not return all of the form fields. Failure Reasons:[Token was not provided;]"* | Our reading of the message: the Microsoft sign-in page tracks one sign-in across several requests with cookies and hidden form fields. When a request in the middle arrives without them, the page can't tie it to the sign-in that started it, and it stops with 165000. The `Failure Reasons` part says which piece was missing. Microsoft hasn't documented this. What users report as the cause: - **Wrong device clock.** In the iPad thread, a community member writes that the iPads that failed had the wrong date and time: *"Fixed time zone and set time to automatic, problem solved."* A second user reports the same fix on an iPad. - **iPad browsers.** The iPad thread saw it in Safari-based and Chrome browsers, after cache clears and even a full wipe. - **One browser only.** In the Edge thread it happened only in Edge, not in Chrome with the same user, and started after the May 2024 Windows Server updates. ## Is it an attack? No, as far as any report we found shows. Every case users describe is a browser or device problem. | Pattern | Likely meaning | |---|---| | One or two users, always on the same iPad | The device clock or cookie settings. Check the date and time first. | | Many users on managed iPads at the same site | A content filter or proxy that changes the sign-in traffic, or a device profile that blocks cookies. The iPad thread used a filtering browser. Our interpretation. | | One browser on one server fails, another works | A browser issue, as in the Edge thread. Use the other browser or the device code workaround below. | | A spike for every user at once | Not seen in any report we found. Check for a network change; this is a guess, not a reported cause. | We found no source that links 165000 to an attack. ## How do I find it in my logs (KQL)? Microsoft doesn't document whether or where 165000 is logged. The admin in the iPad thread writes that the sign-in logs showed error code *"399218"*. Our reading: the sign-in log may record these failures under a different code than the one on the user's screen. Search for both: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType in ("165000", "399218") | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable, ResultType, ResultDescription ``` If rows show up, see which devices and browsers they come from. Concentration on one operating system points at the device, not the tenant: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType in ("165000", "399218") | extend OS = tostring(DeviceDetail.operatingSystem), Browser = tostring(DeviceDetail.browser) | summarize Attempts = count(), Users = dcount(UserPrincipalName), LastSeen = max(TimeGenerated) by OS, Browser, AppDisplayName | sort by Attempts desc ``` If neither query returns anything, look up the user's failed sign-ins at the time of the error and read `ResultType` and `ResultDescription` from there. ## How do I fix AADSTS165000? **For the user:** 1. Set the device's date and time to automatic, with the right time zone. Two users report this fixed it on iPads. 2. Allow cookies in the browser and don't use private browsing for the sign-in. On Safari, a Q&A answer suggests turning off **Prevent Cross-Site Tracking** and **Block All Cookies**. 3. Try another browser. In the Edge thread, Chrome worked with the same account. 4. On a Mac with Microsoft 365 Home, an Independent Advisor on Q&A suggests that a work or school account used on the device before can get in the way, and points to Microsoft's license removal tool for Office on Mac. This one is a single suggestion, not a confirmed fix. **For admins:** 1. Ask which device and browser, and check the clock first. It is the only fix that more than one user reports as working. 2. If a content filter sits in front of the devices, a Q&A answer suggests excluding Microsoft sign-in addresses from it, such as `login.microsoftonline.com`, `login.live.com` and `*.office.com`. Users have not confirmed that this fixed it. 3. The same answer suggests checking Conditional Access sign-in frequency and persistent browser session settings for the affected users. Nobody in the thread reports this as the cause. **For apps that open a browser sign-in (appliances, tools):** the accepted answer in the Edge thread is a workaround: when the error shows, refresh the sign-in tab, or open `https://microsoft.com/devicelogin` in a new tab and enter the device code the app showed. The moderator who posted it said no root cause had been shared yet. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft Q&A: Two of our users are getting the AADSTS165000 error page](https://learn.microsoft.com/en-us/answers/questions/2264720/two-of-our-users-are-getting-the-aadsts165000-erro) 3. [Microsoft Q&A: Azure Site Recovery configuration gives AADSTS165000 when using Edge](https://learn.microsoft.com/en-us/answers/questions/1691539/azure-site-recovery-configuration-gives-aadsts1650) 4. [Microsoft Q&A: AADSTS165000: Invalid Request: The user session context is missing](https://learn.microsoft.com/en-us/answers/questions/5643859/aadsts165000-invalid-request-the-user-session-cont) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/), [AADSTS50140](https://brambrinkmeier.com/entra/aadsts/50140/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS165000: User session context is missing (fix)", https://brambrinkmeier.com/entra/aadsts/165000/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/500011/ # AADSTS500011: The resource principal was not found in the tenant Canonical: https://brambrinkmeier.com/entra/aadsts/500011/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/500011.json **Short answer:** AADSTS500011 means an app asked for a token for an API (the resource) that has no service principal in the tenant the request went to. It is a configuration error: wrong resource URL or scope, wrong tenant, or an API nobody has provisioned or consented to. It has low attack value. Hunt it in SigninLogs and AADServicePrincipalSignInLogs. **Fix:** Developer: compare the resource URL or scope in the error with the API's App ID URI or application ID, and check the request goes to the right tenant. Admin: look for the resource under Enterprise applications; if it is missing and should be used, provision it and grant consent. | Field | Value | |---|---| | Code | AADSTS500011 | | Microsoft name | InvalidResourceServicePrincipalNotFound | | Category | App configuration | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs`, `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-25) | | Last updated | 2026-10-30 | ## What does AADSTS500011 mean? Microsoft's description: > **InvalidResourceServicePrincipalNotFound**: The resource principal named {name} wasn't found in the tenant named {tenant}. This can happen if the application hasn't been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant. If you expect the app to be installed, you might need to provide administrator permissions to add it. Check with the developers of the resource and application to understand what the right setup for your tenant is. The full message users see reads *"AADSTS500011 - The resource principal named [resource URL] was not found in the tenant named [tenant ID]"*. The missing object is the **resource**: the API the app wants a token for. If the missing object is the client app itself, the error is [700016](https://brambrinkmeier.com/entra/aadsts/700016/) instead. Microsoft explains why the object must exist: *"A service principal must be created in each tenant where the application is used."* An API registered in another tenant has no service principal in yours until an admin provisions it or someone consents to it. ## Reproduced in the lab On 25 October 2026 an automated lab run sent a token request for a scope on a resource that doesn't exist in my lab tenant. Entra returned `AADSTS500011` with this first line: > AADSTS500011: The resource principal named https://does-not-exist.brambrinkmeier.com was not found in the tenant named {tenant-id}. That confirms the code and its wording at the token endpoint. The same attempt in the lab tenant's sign-in log (Entra admin center, interactive user sign-ins), with identifiers left out: | Field | Value in the lab row | |---|---| | Status | Failure | | Sign-in error code | 500011 | | Failure reason | The resource principal named {name} was not found in the tenant named {tenant}. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. | | Authentication requirement | Single-factor authentication | | Conditional Access | Not Applied | | User type | Member | The log shows Microsoft's template text with placeholders; the actual resource name appears only in the error returned to the client, so keep the client's error message when you troubleshoot. The KQL below was run on the lab rows ([how](https://brambrinkmeier.com/methodology/)). The first query found both lab rows. The second query reads `AADServicePrincipalSignInLogs`, and the lab rows are user sign-ins, so it is not tested yet. ## Is it an attack? No. Microsoft's troubleshooting article lists four causes, all configuration: - *"The resource application isn't provisioned by the administrator in the tenant."* - *"The resource application isn't consented to by any user in the tenant."* - *"The resource URL is not configured correctly."* - *"The tenant ID is not correct."* | Pattern | Likely meaning | |---|---| | 500011 for one app, every user, starting at a deployment | A typo or wrong value in the resource URL or scope. Developer error. | | 500011 for a vendor's multitenant app after onboarding | The vendor's API was never provisioned or consented in your tenant. Setup step missing. | | 500011 naming a resource you don't recognise, from an app or IP you don't recognise | Someone asking your tenant for tokens to an API you never set up. Our interpretation, not a documented detection: the request failed, but the client and IP are worth a look. | ## How do I find it in my logs (KQL)? User flows, grouped by client and the resource in the request: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType == "500011" | summarize Attempts = count(), Users = dcount(UserPrincipalName), Resources = make_set(ResourceIdentity, 10), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppDisplayName, AppId | sort by Attempts desc ``` App-only flows (client credentials): ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "500011" | summarize Attempts = count(), Resources = make_set(ResourceIdentity, 10), IPs = make_set(IPAddress, 10) by AppId, ServicePrincipalName | sort by Attempts desc ``` The resource in the error doesn't exist in your tenant, so `ResourceIdentity` and `ResourceDisplayName` may be empty on these rows. That isn't documented either way. If they are, the resource URL is in the error text, so look at `ResultDescription` or open one event in the portal. Silent token requests for a missing resource can also land in `AADNonInteractiveUserSignInLogs`; swap the table name in the first query to check. For app-only rows, confirm in your workspace that `ResultType` carries `"500011"` and not *"Failure"*. The Azure Monitor reference for `AADServicePrincipalSignInLogs` describes it as *"Success or Failure"*. If so, filter on `ResultSignature`. ## How does Conditional Access affect it? - 500011 happens before any Conditional Access decision on the resource. There is no resource in your tenant for a policy to target. - Once the resource is provisioned, it gets a service principal and appears as a target in Conditional Access like any other app. Check that your policies cover it before users start using it. ## How do I fix AADSTS500011? **For developers:** 1. Compare the resource URL or scope in the error with the API's App ID URI or application ID. A wrong value here is the most common cause. 2. Check that the request goes to the right tenant, not a tenant where the API was never set up. **For admins:** 1. Look under **Enterprise applications** for the resource named in the error. If it isn't there, it was never provisioned in your tenant. 2. If the API should be used, provision it and grant consent. For a vendor app, ask the vendor for their admin consent link. Microsoft documents an admin consent endpoint (`https://login.microsoftonline.com/{tenant}/v2.0/adminconsent`) that apps use to *"grant permissions to an entire tenant"*. 3. Before consenting, check what the API's permissions allow. Provisioning a resource creates a service principal in your tenant that *"defines what the app can actually do in the specific tenant"*. ## Evidence Reproduced in a lab tenant on 2026-10-25 (ROPC token request against a lab tenant; scenario: Resource does not exist in tenant). First line returned: > AADSTS500011: The resource principal named https://does-not-exist.brambrinkmeier.com was not found in the tenant named {tenant-id}. Sign-in log row read: 2026-10-30. KQL run against the exported lab rows: 2026-10-30. Lab-run rows naming this code (9; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Resource does not exist in tenant | 500011 | 500011 | AADSTS500011: The resource principal named https://does-not-exist.brambrinkmeier.com was not found in the tenant named {tenant-id}. Thi | | 2026-10-30 | Resource does not exist in tenant | 500011 | 500011 | AADSTS500011: The resource principal named https://does-not-exist.brambrinkmeier.com was not found in the tenant named {tenant-id}. Thi | | 2026-10-30 | Resource does not exist in tenant | 500011 | 500011 | AADSTS500011: The resource principal named https://does-not-exist.brambrinkmeier.com was not found in the tenant named {tenant-id}. Thi | | 2026-10-30 | Resource does not exist in tenant | 500011 | 500011 | AADSTS500011: The resource principal named https://does-not-exist.brambrinkmeier.com was not found in the tenant named {tenant-id}. Thi | | 2026-10-30 | Resource does not exist in tenant | 500011 | 500011 | AADSTS500011: The resource principal named https://does-not-exist.brambrinkmeier.com was not found in the tenant named {tenant-id}. Thi | | 2026-10-30 | Resource does not exist in tenant | 500011 | 500011 | AADSTS500011: The resource principal named https://does-not-exist.brambrinkmeier.com was not found in the tenant named {tenant-id}. Thi | | 2026-10-30 | Resource does not exist in tenant | 500011 | 500011 | AADSTS500011: The resource principal named https://does-not-exist.brambrinkmeier.com was not found in the tenant named {tenant-id}. Thi | | 2026-10-31 | Resource does not exist in tenant | 500011 | 500011 | AADSTS500011: The resource principal named https://does-not-exist.brambrinkmeier.com was not found in the tenant named {tenant-id}. Thi | | 2026-10-31 | Resource does not exist in tenant | 500011 | 500011 | AADSTS500011: The resource principal named https://does-not-exist.brambrinkmeier.com was not found in the tenant named {tenant-id}. Thi | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [AADSTS500011 - Resource principal not found (Microsoft troubleshooting)](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts500011-resource-principal-not-found) 3. [Application and service principal objects in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals) 4. [Admin consent on the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/v2-admin-consent) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 6. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS7000222](https://brambrinkmeier.com/entra/aadsts/7000222/), [AADSTS50001](https://brambrinkmeier.com/entra/aadsts/50001/), [AADSTS50013](https://brambrinkmeier.com/entra/aadsts/50013/), [AADSTS65002](https://brambrinkmeier.com/entra/aadsts/65002/), [AADSTS65005](https://brambrinkmeier.com/entra/aadsts/65005/), [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS90009](https://brambrinkmeier.com/entra/aadsts/90009/), [AADSTS90133](https://brambrinkmeier.com/entra/aadsts/90133/), [AADSTS500014](https://brambrinkmeier.com/entra/aadsts/500014/), [AADSTS501051](https://brambrinkmeier.com/entra/aadsts/501051/), [AADSTS650052](https://brambrinkmeier.com/entra/aadsts/650052/), [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/), [AADSTS901002](https://brambrinkmeier.com/entra/aadsts/901002/), [AADSTS7000112](https://brambrinkmeier.com/entra/aadsts/7000112/), [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS9010010](https://brambrinkmeier.com/entra/aadsts/9010010/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS500011: The resource principal was not found in the tenant", https://brambrinkmeier.com/entra/aadsts/500011/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/500014/ # AADSTS500014 fix: resource service principal is disabled Canonical: https://brambrinkmeier.com/entra/aadsts/500014/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/500014.json **Short answer:** AADSTS500014 means the API a token was requested for (the resource) has a disabled service principal in the tenant, so Microsoft Entra ID won't issue tokens for it. Microsoft gives two causes: a lapsed subscription or an admin who disabled it. If the resource is a Microsoft service such as Exchange Online, sign-ins break for everyone. Find who disabled it before re-enabling. **Fix:** Admin: check the audit log for who disabled the resource named in the error, then set Enterprise applications > that app > Properties > Enabled for users to sign-in? to Yes if it was a mistake. Check the subscription is active. User: tell IT the resource named in the error. | Field | Value | |---|---| | Code | AADSTS500014 | | Microsoft name | InvalidResourceServicePrincipalDisabled | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS500014 mean? Microsoft's description: > **InvalidResourceServicePrincipalDisabled**: The service principal for resource '{identifier}' is disabled. This indicates that a subscription within the tenant has lapsed, or that an administrator for this tenant has disabled the application's service principal, preventing tokens from being issued for it. For more information, see Disable user sign-in for application. The disabled object is the **resource**: the API the token is for, named in the error. The client app the user opened can be perfectly fine. The switch is the enterprise application's **Enabled for users to sign-in?** property. Microsoft describes what **No** does: *"no users are able to sign in to the application, even if they're assigned to it. Tokens aren't issued for the application. This setting not only prevents users from signing in but also restricts service principals from accessing the application using application permissions."* In Microsoft Graph it is the service principal's `accountEnabled` property. **How it differs from [7000112](https://brambrinkmeier.com/entra/aadsts/7000112/):** both come from the same switch. Our reading: 7000112 is returned when the disabled app is the **client** being signed in to, and 500014 when it is the **resource** a token is requested for. Microsoft's Exchange Online troubleshooting article shows 7000112 for a disabled Exchange Online service principal on the Microsoft 365 portal. Users report 500014 for the same disabled service principal when Exchange is the resource, for example in Outlook sync tools. Which code you get depends on the request; Microsoft doesn't spell this out. Treat the split as a rough guide: in Microsoft's own Exchange example, Exchange is arguably the resource, and it still shows 7000112. **How it differs from [500011](https://brambrinkmeier.com/entra/aadsts/500011/):** 500011 means the resource has **no** service principal in the tenant. 500014 means it has one and it is switched off. ## Is it an attack? The error itself is not. It is a block working. What matters is who disabled the resource, and whether it was a Microsoft service. | Pattern | Likely meaning | |---|---| | 500014 for your own API, after someone disabled it | Working as intended. Clients can no longer get tokens for it. | | 500014 naming a Microsoft service (Exchange Online, a Microsoft app ID) for many users, or on the Azure portal | Someone disabled a Microsoft service principal in your tenant, or a subscription lapsed. Users report it for the Azure portal, with Microsoft Graph as the resource, and for Dynamics environments. Check the audit log first. | | 500014 for a Dynamics 365 environment URL with an active subscription | Users report this too. The environment's service principal may be disabled; check its **Enabled for users to sign-in?** setting. | | 500014 after a licence or trial ended | Microsoft names a lapsed subscription as a cause. | A disabled Microsoft first-party service principal is worth a second look. Our reading, not a Microsoft statement: if nobody on your team disabled it on purpose, treat the account that did as suspect until you know, because switching off a core service is a quick way to cause a tenant-wide outage. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 500014 lands in. A disabled resource blocks both user and app-only tokens, so it can appear in all three. Check where it lands: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "500014" | summarize Rows = count(), Resources = dcount(ResourceIdentity) by SourceTable ``` Which resources are disabled, how many users and apps are hitting them, and since when: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "500014" | summarize Rows = count(), Users = dcount(UserPrincipalName), ClientApps = make_set(coalesce(AppDisplayName, ServicePrincipalName), 10), FirstSeen = min(TimeGenerated) by ResourceIdentity, ResourceDisplayName | sort by Users desc ``` Who changed a service principal, and when. Microsoft's audit log reference lists **Update service principal** in the ApplicationManagement category. Disabling an enterprise app is likely logged as that activity; Microsoft doesn't say so: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where Category == "ApplicationManagement" | where OperationName == "Update service principal" | mv-expand Target = TargetResources | mv-expand Prop = Target.modifiedProperties | where tostring(Prop.displayName) == "AccountEnabled" | project TimeGenerated, App = tostring(Target.displayName), ServicePrincipalId = tostring(Target.id), OldValue = tostring(Prop.oldValue), NewValue = tostring(Prop.newValue), ByUser = tostring(InitiatedBy.user.userPrincipalName), ByApp = tostring(InitiatedBy.app.displayName) | sort by TimeGenerated desc ``` The modified property name `AccountEnabled` is an assumption based on the Graph property, not checked against Microsoft documentation. If the query returns nothing, drop that line and read the `modifiedProperties` of the rows yourself. Non-interactive and service principal sign-in rows are aggregated, so row counts there are not request counts. `ResultType` is a **string** column, so compare it with `"500014"`. ## How does Conditional Access affect it? - 500014 is not a Conditional Access block. A disabled resource gets no tokens, whatever your policies say. - Don't confuse it with [53003](https://brambrinkmeier.com/entra/aadsts/53003/), which is a Conditional Access block. The fix and the owner are different. ## How do I fix AADSTS500014? **For the user:** you can't fix this yourself. Tell your IT team which resource the error names. **For developers:** if your API is the resource and a customer gets 500014, the customer's admin disabled your API's service principal in their tenant, or their subscription lapsed. You can't re-enable it from your side. **For admins:** 1. Read the resource from the error. Find it under **Enterprise applications** (remove the default filters and search by application ID). 2. Find out who disabled it and why with the audit log query, before changing anything. If it was disabled during an incident, leave it. 3. Check that the subscription behind the service is active. Microsoft names a lapsed subscription as the other cause. 4. If it was a mistake: in **Enterprise applications** > the app > **Properties**, set **Enabled for users to sign-in?** to **Yes**. In Microsoft Graph, set `accountEnabled` to `true`. Microsoft documents `accountEnabled` as *"`true` if the service principal account is enabled"*. With Microsoft Graph PowerShell: ```powershell Connect-MgGraph -Scopes "Application.ReadWrite.All" $sp = Get-MgServicePrincipal -Filter "appId eq ''" $sp.AccountEnabled Update-MgServicePrincipal -ServicePrincipalId $sp.Id -AccountEnabled:$true ``` This mirrors Microsoft's disable command with `$true`. Microsoft's page shows only the disable direction. 5. For Exchange Online, the app ID is `00000002-0000-0ff1-ce00-000000000000`. Microsoft's article uses the deprecated MSOnline module for this; use Microsoft Graph PowerShell as above. 6. If the app registration was **deactivated** globally by its owner, that is a different switch (`isDisabled`). Microsoft notes that reactivating it *"doesn't enable tenant-local sign-in if a service principal's `accountEnabled` remains `false`"*. Check both. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Disable user sign-in for an application](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/disable-user-sign-in-portal) 3. [Properties of an enterprise application](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/application-properties) 4. [servicePrincipal resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/serviceprincipal) 5. [Deactivate an app registration](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/deactivate-app-registration) 6. ["Sorry, but we're having trouble signing you in" error when signing in to Microsoft 365](https://learn.microsoft.com/en-us/microsoft-365/troubleshoot/sign-in/exchange-online-application-service-principal-disabled) 7. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) 8. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 9. [Microsoft Tech Community: Response AADSTS500014 error (user reports)](https://techcommunity.microsoft.com/discussions/teamsdeveloper/response-aadsts500014-error/3888448/replies/3890142) 10. [Microsoft Q&A: Azure portal sign-in failed, AADSTS500014 (user report)](https://learn.microsoft.com/en-us/answers/questions/1690153/azule-portal-issue-sign-in-failed-error-code-aadst) 11. [Microsoft Q&A: The service principal for resource is disabled (user report)](https://learn.microsoft.com/en-us/answers/questions/1187462/the-service-principal-for-resource-is-disabled-tok) 12. [Sync365 KB: AADSTS500014 Exchange Online service principal disabled (vendor KB)](https://s365.freshdesk.com/support/solutions/articles/51000466956-aadsts500014-exchange-online-service-principal-disabled-fix-disabled-service-principal-for-outlook) ## Related codes [AADSTS7000112](https://brambrinkmeier.com/entra/aadsts/7000112/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS650052](https://brambrinkmeier.com/entra/aadsts/650052/), [AADSTS50001](https://brambrinkmeier.com/entra/aadsts/50001/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS500014 fix: resource service principal is disabled", https://brambrinkmeier.com/entra/aadsts/500014/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/500021/ # AADSTS500021 fix: tenant blocked by tenant restrictions Canonical: https://brambrinkmeier.com/entra/aadsts/500021/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/500021.json **Short answer:** AADSTS500021 means tenant restrictions (v1) are on in the user's network: a proxy adds a list of allowed tenants to sign-in traffic, and the tenant the user tried to reach isn't on it. It is a control doing its job, with low attack value. The fix is on the side of whoever runs the proxy, usually the user's own organisation, not the app's tenant. **Fix:** User: you are on a network that only allows certain tenants; ask your own IT team to allow this one. Admin of the network: add the tenant's ID or domain to the Restrict-Access-To-Tenants header on your proxy. App owner: you can't fix this from your tenant; the user's IT team must. | Field | Value | |---|---| | Code | AADSTS500021 | | Category | Guests and tenants | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS500021 mean? Microsoft's description: > Access to '{tenant}' tenant is denied. AADSTS500021 indicates that the tenant restriction feature is configured and that the user is trying to access a tenant that isn't in the list of allowed tenants specified in the header `Restrict-Access-To-Tenant`. For more information, see Use tenant restrictions to manage access to SaaS cloud applications. Microsoft gives this code no name. The block comes from the **network**, not from the tenant the user is signing in to. Tenant restrictions (the original version, which Microsoft's v2 page calls *"Tenant restrictions v1"*) work like this. A corporate proxy that does TLS inspection adds two headers to every request to `login.microsoftonline.com`, `login.microsoft.com` and `login.windows.net`: - `Restrict-Access-To-Tenants`: *"a comma-separated list of tenants you want to allow users to access"*. - `Restrict-Access-Context`: *"a single directory ID, declaring which tenant is setting the tenant restrictions"*. If the tenant the user tries to reach isn't on the list, sign-in fails. Microsoft's tenant restrictions page says the user *"sees an access denial message"* about *"a resource that belongs to an organization unapproved by your IT department."* Microsoft's error description writes the header as `Restrict-Access-To-Tenant`; the tenant restrictions page spells it `Restrict-Access-To-Tenants`, with an s. Use the page's spelling on your proxy. ### v1 or v2? Be precise here, because the two versions use different headers and, as far as Microsoft documents, different codes. | | Tenant restrictions v1 | Tenant restrictions v2 | |---|---|---| | Where the allow list lives | In the proxy header itself | *"moved to the server-side cloud policy"* (cross-tenant access settings) | | Header | `Restrict-Access-To-Tenants` + `Restrict-Access-Context` | `sec-Restrict-Tenant-Access-Policy: :` | | Enforcement | Corporate proxy only | Proxy, Windows devices (Group Policy) or Global Secure Access | | Protects | Authentication plane | Authentication plane, plus data plane with device signalling | | Code Microsoft shows | **500021** (error reference) | **[5000211](https://brambrinkmeier.com/entra/aadsts/5000211/)** (v2 setup page) | So: 500021 points at a v1 allow list on a proxy. If the message says *"A tenant restrictions policy added to this request by a device or network administrator"*, you are looking at v2 and 5000211. Microsoft notes that migrating from v1 to v2 *"is a one-time operation"*. ## Is it an attack? No. It is a block working as designed. Tenant restrictions exist to stop users signing in to tenants their organisation hasn't approved, for example a personal or competitor tenant used to move data out. | Pattern | Likely meaning | |---|---| | A guest from a customer or partner organisation gets 500021 on your app | Their IT runs tenant restrictions and your tenant isn't on their list. Users report exactly this in Microsoft Q&A, including for Power BI shared with external customers. | | Your own users get 500021 when opening a partner's app | Your proxy doesn't list the partner's tenant. Add it if the access is approved. | | Your own users get 500021 for a tenant nobody recognises | The control stopped a sign-in to an unapproved tenant. Our interpretation: worth asking the user why, because this is the data-leak path tenant restrictions are meant to close. | | 500021 started for many users at once | Someone changed the proxy's allow list, or traffic moved to a proxy with a different list. | ## How do I find it in my logs (KQL)? Microsoft gives the admin of the `Restrict-Access-Context` tenant a dedicated report: **Entra ID** > **Overview** > **Tenant restrictions**. It shows *"sign-ins blocked because of the tenant restrictions policy, including the identity used and the target directory ID."* Microsoft adds that *"Sign-ins are included if the tenant setting the restriction is either the user tenant or resource tenant for the sign-in"*, and that identities from other tenants are masked. Microsoft doesn't document which Log Analytics table 500021 rows land in, or in which tenant's workspace. Check yours: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "500021" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Which target tenants are being blocked, for whom, and from which egress IPs (each egress IP points at a proxy): ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "500021" | summarize Rows = count(), Users = dcount(UserPrincipalName), Apps = make_set(AppDisplayName, 5), EgressIPs = make_set(IPAddress, 10) by HomeTenantId, ResourceTenantId, IsTenantRestricted | sort by Users desc ``` The `IsTenantRestricted` column is documented as *"Indicates if a signIn is under a tenant restrictions policy or not."* Whether Microsoft sets it on 500021 rows isn't documented. If it does, this finds every sign-in under a restrictions policy, blocked or not: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where IsTenantRestricted == true | summarize Rows = count(), Users = dcount(UserPrincipalName) by ResultType, ResourceTenantId | sort by Rows desc ``` `ResultType` is a **string** column, so compare it with `"500021"`. ## How does Conditional Access affect it? - 500021 is not a Conditional Access block. The proxy header decides it, whatever the target tenant's policies say. - Don't confuse it with [53003](https://brambrinkmeier.com/entra/aadsts/53003/), which is a Conditional Access block in the target tenant. The owner of the fix is different. - Cross-tenant access settings for B2B collaboration are also a different control. One Q&A answer suggests changing outbound B2B settings for this error. Microsoft's description of 500021 points only at the v1 header, so start there. ## How do I fix AADSTS500021? **For the user:** the network you are on only allows sign-in to approved tenants. Ask **your own** IT team to allow the tenant you need. If you are a guest on someone else's app, the app's owner can't fix this for you. **For app owners and B2B hosts:** you can't fix this from your tenant. Tell the guest's IT team your tenant ID or verified domain and ask them to add it to their tenant restrictions list. Users in Microsoft Q&A report this is the step that's missing. **For admins who run the proxy:** 1. Find the proxy rule that adds `Restrict-Access-To-Tenants` to traffic for the Microsoft sign-in hosts. 2. Add the target tenant. Microsoft says *"Any domain that is registered with a tenant can be used to identify the tenant in this list, and the directory ID itself."* Microsoft's example: `Restrict-Access-To-Tenants: contoso.com,fabrikam.onmicrosoft.com,{guid}`. 3. Keep `Restrict-Access-Context` set to **your own** directory ID. Microsoft warns that with any other ID *"the sign-in logs appear in someone else's tenant, with all personal information removed."* 4. Before you allow a tenant nobody asked for, check why users tried to reach it. 5. If you are moving to tenant restrictions v2, the allow list moves into cross-tenant access settings and the v1 header should be removed from the proxy. Blocks then show as [5000211](https://brambrinkmeier.com/entra/aadsts/5000211/). ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Use tenant restrictions to manage access to SaaS cloud applications](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/tenant-restrictions) 3. [Set up tenant restrictions v2](https://learn.microsoft.com/en-us/entra/external-id/tenant-restrictions-v2) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 5. [Microsoft Q&A: Diagnosing and fixing AADSTS500021 (user reports)](https://learn.microsoft.com/en-us/answers/questions/2201407/diagnosing-and-fixing-aadsts500021) 6. [Microsoft Q&A: Edit Restrict-Access-To-Tenants to external tenant (user reports)](https://learn.microsoft.com/en-us/answers/questions/661557/edit-restrict-access-to-tenants-to-external-tenant) ## Related codes [AADSTS5000211](https://brambrinkmeier.com/entra/aadsts/5000211/), [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS90072](https://brambrinkmeier.com/entra/aadsts/90072/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS500021 fix: tenant blocked by tenant restrictions", https://brambrinkmeier.com/entra/aadsts/500021/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/500031/ # AADSTS500031: Signing certificate for the app not found (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/500031/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/500031.json **Short answer:** AADSTS500031 means Entra couldn't find a signing certificate configured for the app. Microsoft doesn't list the code. The one user report we found was fixed by adding a SAML signing certificate to the enterprise app. It is a configuration error with low attack value. Check the app's SAML Certificates section and make sure a valid certificate is active. **Fix:** Admin: open the enterprise app > Single sign-on > SAML Certificates > Edit. If no certificate is there, select New Certificate, Save, then Make certificate active, and give it to the app vendor. This fixed the one user report we found. User: tell IT which app failed. | Field | Value | |---|---| | Code | AADSTS500031 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS500031 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS500031 (checked 30 October 2026). The wording below comes from a user report. A user on Microsoft Q&A posted this response from the token endpoint (`/oauth2/v2.0/token`): ``` HttpResponseCode = 400 (BadRequest) ErrorMsg: AADSTS500031: Cannot find signing certificate configured ``` The user's app was an Angular single-page app using the authorization code flow. It failed with two different client libraries. The user's own accepted answer: *"After adding a missing SAML certificate it works!"* The steps were **Enterprise applications** > the app > **Single sign-on** > **SAML** > add the missing **SAML Signing Certificate**. That is one report, from 2020. It shows one cause and one fix. It doesn't explain the mechanism. Our reading: Entra signs the tokens it issues for an app. When an enterprise app has its own signing certificate setting, as SAML apps do, Entra looked for it and found none. A documented relative exists. [Microsoft's troubleshooting article](https://learn.microsoft.com/troubleshoot/azure/active-directory/error-code-aadsts50003-cert-or-key-not-configured) for AADSTS50003, *"No signing key configured"*, covers SAML apps where *"Microsoft Entra ID doesn't recognize the certificate configured for the application."* Its fix is the same: create a new certificate and make it active. ## Is it an attack? No. The user report points to a configuration error on the enterprise app. Our reading: the certificate is missing on Entra's side, so a caller can't cause it by changing the request, and everyone who uses the app fails at once. | Pattern | Likely meaning | |---|---| | Every user of one app fails at the same moment | The signing certificate was removed, or never added. Likely, but unconfirmed. | | A new SAML app fails on its first test | Single sign-on was set up but no certificate was saved. Likely; we haven't tested this. | | The app worked for years, then failed | Check the certificate's expiry date. Microsoft's certificate tutorial describes rollover and expiry. Whether an expired certificate produces this code is not documented. | | An OAuth or OpenID Connect app fails with it | The user report above. The enterprise app had SAML settings without a certificate. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table AADSTS500031 is logged in. The user has signed in by then, so `SigninLogs` is the likely table. Check all three: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "500031" | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable ``` Which apps fail, how many users, and over which protocol: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "500031" | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppId, AppDisplayName, AuthenticationProtocol | sort by Users desc ``` When the app last worked, which tells you when the certificate went missing: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where AppId == "" | summarize LastSuccess = maxif(TimeGenerated, ResultType == "0"), FirstFailure = minif(TimeGenerated, ResultType == "500031") ``` If `LastSuccess` is just before `FirstFailure`, look in the audit log for changes to the app around that time. ## How do I fix AADSTS500031? **For the user:** you can't fix this. Tell IT which app failed. Everyone else is likely affected too. **For admins:** 1. Open the Microsoft Entra admin center as at least a Cloud Application Administrator. Go to **Entra ID** > **Enterprise apps** > **All applications** and open the app. 2. Go to **Single sign-on**. Under **SAML Certificates**, select **Edit**. The page shows the status (**Active** or **Inactive**), expiry date and thumbprint of each certificate. 3. If there is no certificate, select **New Certificate** and **Save**. A new certificate starts as **Inactive**. 4. On the new row, select **...** > **Make certificate active**. 5. If the app is a SAML app, give the new certificate to the app or its vendor. Microsoft's tutorial says to download it from the **SAML Certificates** section. 6. Watch for the expiry emails. Microsoft says it sends one *"60, 30, and 7 days before the SAML certificate expires."* **For developers:** if your OAuth or OpenID Connect app gets this error, check whether its enterprise app has single sign-on set to SAML with no certificate. Ask an admin to check the steps above. That is what fixed the user report. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [AADSTS500031: Cannot find signing certificate configured (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/141320/aadsts500031-cannot-find-signing-certificate-confi) 3. [Tutorial: Manage certificates for federated single sign-on](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/tutorial-manage-certificates-for-federated-single-sign-on) 4. [Error AADSTS50003 - No signing key configured](https://learn.microsoft.com/troubleshoot/azure/active-directory/error-code-aadsts50003-cert-or-key-not-configured) 5. [SigninLogs table reference (Azure Monitor)](https://docs.azure.cn/en-us/azure-monitor/reference/tables/SigninLogs) ## Related codes [AADSTS75011](https://brambrinkmeier.com/entra/aadsts/75011/), [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS500031: Signing certificate for the app not found (fix)", https://brambrinkmeier.com/entra/aadsts/500031/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/500113/ # AADSTS500113: No reply address is registered for the app (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/500113/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/500113.json **Short answer:** AADSTS500113 means a sign-in request went to the authorize endpoint for an app registration that has no redirect URI (reply address) at all. Entra has no allowed place to send the result and refuses the request, even before anyone signs in. It is a configuration error with low attack value. Add the right platform and redirect URI to the app registration. **Fix:** Developer or admin: in App registrations, open the app > Authentication > Add Redirect URI, pick the platform that matches the app, and enter the exact URI the app sends. User: you can't fix this yourself; report the app name to whoever set it up. | Field | Value | |---|---| | Code | AADSTS500113 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS500113 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS500113 (checked 30 October 2026). In my lab tenant, an unauthenticated authorize request in a browser, for an app registration with no redirect URI, showed this error on the page: > AADSTS500113: No reply address is registered for the application. "Reply address" is the older name for a redirect URI. Microsoft's redirect URI page explains why Entra needs one: *"To sign in a user, your application must send a login request to the Microsoft Entra authorization endpoint, with a redirect URI specified as a parameter. The redirect URI is a critical security feature that ensures the Microsoft Entra authentication server only sends authorization codes and access tokens to the intended recipient."* Our reading: with no redirect URI registered at all, there is no allowed place to send the result, so Entra refuses the request. A Microsoft moderator on [Microsoft Q&A](https://learn.microsoft.com/en-us/answers/questions/183594/aadsts500113-no-reply-address-is-registered-for-th) gave the same reading: *"The error states that the reply URL is not available, hence to fix this, you need to add a valid RedirectURI/ReplyURL in your app registration in AAD."* Don't confuse it with [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), which Microsoft does list. Our reading of the difference: 50011 means the app has redirect URIs but the one in the request doesn't match; 500113 means the app has none. ## Reproduced in the lab In a manual lab test on 30 October 2026, an authorize URL for a lab app registration with no redirect URI was opened in a private browser window, without signing in. Entra showed `AADSTS500113` on its error page with this first line: > AADSTS500113: No reply address is registered for the application. That confirms the code and its wording at the authorize endpoint. It also shows the error doesn't need a signed-in user: the request was unauthenticated. It lands in **`SigninLogs`**, and the row was logged under the account that was already signed in to that browser (the lab admin), with client app "Browser". So the user on a 500113 row can be whoever had a session, not someone who typed a password. The KQL below was run on these rows ([how](https://brambrinkmeier.com/methodology/)). The first query found the row. The `AuditLogs` query isn't tested: the export has no audit rows. ## Is it an attack? No. It is an app registration that is missing its redirect URI. | Pattern | Likely meaning | |---|---| | A new app registration, first test sign-in | The developer created the registration and never added a platform. | | A desktop or mobile app (for example an Android app) fails on first interactive sign-in | The registration has no **Mobile and desktop applications** platform. Users report this on [Microsoft Q&A](https://learn.microsoft.com/en-us/answers/questions/183594/aadsts500113-no-reply-address-is-registered-for-th) (Android) and the [Icewolf blog](https://blog.icewolf.ch/archive/2021/07/06/aad-delegated-login-fix-error-aadsts500113-no-reply-address-is/) (delegated login). | | An app registration made for a background service is now used for user sign-in | Likely: app-only (client credentials) apps don't use the authorize endpoint, so they never needed a redirect URI. Microsoft doesn't say this; a user commenter on the same Q&A thread does. | | An app that worked and now fails | Someone removed its redirect URIs. Check the audit log (query below). | An attacker who sends this request probably learns only that the app has no redirect URI. Nobody is signed in and nothing is issued. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 500113 is logged in. The lab run above logged it in `SigninLogs`, under the account that already had a session in the browser. Check both user sign-in tables: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "500113" | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, AppId, AppDisplayName ``` The audit log is more useful. If the app used to work, find who changed its registration: ```kusto AuditLogs | where TimeGenerated > ago(90d) | where OperationName == "Update application" | mv-expand Target = TargetResources | where tostring(Target.displayName) == "" | mv-expand Prop = Target.modifiedProperties | project TimeGenerated, Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)), Property = tostring(Prop.displayName), OldValue = tostring(Prop.oldValue), NewValue = tostring(Prop.newValue) | sort by TimeGenerated desc ``` The table reference documents `TargetResources` and `InitiatedBy` only as dynamic columns. The field names inside them (`displayName`, `modifiedProperties`, `user.userPrincipalName`) aren't documented there, and neither is the operation name `Update application`. Look for a property whose old value held URLs and whose new value is empty. ## How do I fix AADSTS500113? **For the user:** you can't fix this yourself. Report the app name to whoever set it up. **For developers and admins:** add a platform and redirect URI to the app registration. Microsoft's steps: 1. In the Microsoft Entra admin center, in **App registrations**, select the application. 2. Under **Manage**, select **Authentication**. 3. Select **Add Redirect URI** (on the **Redirect URI configuration** tab). 4. Pick the platform that matches the app: **Web**, **Single-page application**, **iOS / macOS**, **Android** or **Mobile and desktop applications**. 5. Enter or select the redirect URI, then select **Configure**. Microsoft: *"For Web and Single-page applications, you specify a redirect URI manually. For Mobile and desktop platforms, you select from generated redirect URIs."* Use the exact URI the app sends. If it then fails with [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), the URI you added doesn't match the one in the request. If the app is only meant to run as a background service, it shouldn't be sending users to the authorize endpoint at all. Our reading: switch it to the client credentials flow rather than adding a redirect URI it doesn't need. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Authorize request in a browser against a lab tenant; scenario: Authorize request for an app with no reply address (browser)). First line returned: > AADSTS500113: No reply address is registered for the application. Sign-in log row read: 2026-10-30. KQL run against the exported lab rows: 2026-10-30. Lab-run rows naming this code (1; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Authorize request for an app with no reply address (browser) | 500113 | 500113 | AADSTS500113: No reply address is registered for the application. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [How to add a redirect URI to your application](https://learn.microsoft.com/entra/identity-platform/how-to-add-redirect-uri) 3. [Microsoft Q&A: AADSTS500113: No reply address is registered for the application](https://learn.microsoft.com/en-us/answers/questions/183594/aadsts500113-no-reply-address-is-registered-for-th) 4. [Icewolf blog: AAD delegated login, fix error AADSTS500113](https://blog.icewolf.ch/archive/2021/07/06/aad-delegated-login-fix-error-aadsts500113-no-reply-address-is/) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 6. [AuditLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/auditlogs) ## Related codes [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), [AADSTS700051](https://brambrinkmeier.com/entra/aadsts/700051/), [AADSTS700054](https://brambrinkmeier.com/entra/aadsts/700054/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS500113: No reply address is registered for the app (fix)", https://brambrinkmeier.com/entra/aadsts/500113/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/500121/ # AADSTS500121: User didn't complete the MFA prompt Canonical: https://brambrinkmeier.com/entra/aadsts/500121/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/500121.json **Short answer:** AADSTS500121 means the user didn't complete the MFA prompt: it was denied, ignored, timed out, or MFA setup was unfinished. The password had already been accepted. A few are normal. Many for one user in a short window, especially from an unfamiliar IP, is the MFA fatigue pattern. **Fix:** User: if you didn't start the sign-in, deny the prompt and report it; if you are setting up MFA, finish registration and sign in again. Admin: for a burst from an unfamiliar IP, reset the user's password, and if a success followed, revoke the user's sessions. | Field | Value | |---|---| | Code | AADSTS500121 | | Microsoft name | MFA prompt not completed | | Category | Multifactor authentication | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1621](https://attack.mitre.org/techniques/T1621/) Multi-Factor Authentication Request Generation | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS500121 mean? Microsoft's description: > **500121**: User didn't complete the MFA prompt. Microsoft's troubleshooting guide adds that it *"often appears if the user hasn't completed setting up MFA"*. **Where this is documented:** this code is described in Microsoft's [How to troubleshoot sign-in errors](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/howto-troubleshoot-sign-in-errors) guide, not in the main error code reference table. When this page was written (2026-10-11) the reference table had no row for 500121, so there is no PascalCase name to quote. ## Is it an attack? Most 500121 rows are users who closed the prompt, had no signal, or hadn't finished setting up MFA. **The security reading is about volume per user and the source IP.** Microsoft frames this code as troubleshooting; the MFA fatigue reading below is reasoning from what the code means, not a Microsoft statement. | Pattern | Likely meaning | |---|---| | One 500121, then `0` from the same IP and device | The user retried. Benign. | | 500121 for a user who is mid-onboarding | Unfinished MFA setup, as Microsoft describes. | | Many 500121 for **one user** in a short window from an IP the user doesn't use | **MFA fatigue** (T1621). The first factor (usually the password) succeeded and the attacker is pushing prompts. | | A 500121 burst followed by `0` from the **same IP** | **The user gave in and approved.** Treat as account takeover. | | 500121 mixed with **50074** for the same user and IP | Same picture. See [50074](https://brambrinkmeier.com/entra/aadsts/50074/). | Microsoft's password spray playbook says to *"record successful passwords but failed MFA responses, as this activity indicates that the attacker is getting the password but not passing MFA."* Every 500121 means the first factor (usually the password) succeeded. ## How do I find it in my logs (KQL)? Users with repeated 500121 from one IP within an hour: ```kusto SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "500121" | summarize NotCompleted = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Apps = make_set(AppDisplayName, 5) by UserPrincipalName, IPAddress, bin(TimeGenerated, 1h) | where NotCompleted >= 3 | sort by NotCompleted desc ``` Did a fatigued user approve in the end? Successes from the same IP within an hour after the last unfinished prompt: ```kusto let fatigued = SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "500121" | summarize NotCompleted = count(), LastNotCompleted = max(TimeGenerated) by UserPrincipalName, IPAddress | where NotCompleted >= 3; SigninLogs | where TimeGenerated > ago(1d) | where ResultType == "0" | join kind=inner fatigued on UserPrincipalName, IPAddress | where TimeGenerated between (LastNotCompleted .. (LastNotCompleted + 1h)) | project TimeGenerated, UserPrincipalName, IPAddress, NotCompleted, AppDisplayName, UserAgent | sort by TimeGenerated asc ``` The threshold of 3 is a starting point, not a Microsoft number. `ResultType` is a **string** column, so compare it with `"500121"`. ## How do Conditional Access and MFA affect it? - 500121 is the MFA step holding. Whatever required MFA stopped a sign-in whose first factor had succeeded. - The risk is the user approving on the next attempt. Push approval without context is what fatigue attacks rely on. Number matching is enforced for Microsoft Authenticator push since 2023; phishing-resistant methods remove the push entirely. The [MFA fatigue guide](https://brambrinkmeier.com/guides/detect-mfa-fatigue-entra-id/) walks through the investigation. - Microsoft notes that requiring reauthentication too often *"can increase security friction to a point that it causes users to experience MFA fatigue"*. A user who sees prompts all day is easier to fatigue. ## How do I fix AADSTS500121? **For the user:** if you didn't start the sign-in, deny the prompt and report it. If you're setting up MFA, finish registration and sign in again. **For admins:** 1. For a burst from an unfamiliar IP, reset the user's password. The attacker already has it. 2. Run the second query. If a `0` followed, revoke sessions (`Revoke-MgUserSignInSession`) and review what the session accessed. 3. Move users to phishing-resistant MFA, and check any third-party or NPS-extension MFA path that still allows a plain approve. 4. For onboarding users stuck here, help them finish MFA registration. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [How to troubleshoot sign-in errors](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/howto-troubleshoot-sign-in-errors) 2. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 3. [Conditional Access: session lifetime](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-session-lifetime) 4. [Revoke user access in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/users/users-revoke-access) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50074](https://brambrinkmeier.com/entra/aadsts/50074/), [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS50079](https://brambrinkmeier.com/entra/aadsts/50079/), [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS500121: User didn't complete the MFA prompt", https://brambrinkmeier.com/entra/aadsts/500121/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/500200/ # AADSTS500200: Personal Microsoft account not supported by this app (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/500200/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/500200.json **Short answer:** AADSTS500200 means someone signed in with a personal Microsoft account (for example Outlook.com, or a Gmail address used as a Microsoft account) to an app or tenant that only accepts work or school accounts. Microsoft's error reference doesn't list it. It has low attack value. Sign in with a work account, invite the person as a guest, or change the app's supported account types. **Fix:** User: sign out and sign in with your work or school account, or ask the organization's admin to invite you. Admin: invite the person as a guest. Developer: set Supported account types to AzureADandPersonalMicrosoftAccount and sign in through /common or /consumers. | Field | Value | |---|---| | Code | AADSTS500200 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS500200 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS500200 (checked 30 October 2026). We found no Microsoft documentation page for it either. The wording below comes from user reports on Microsoft Q&A. Two separate threads quote the same message: > AADSTS500200: User account '…' is a personal Microsoft account. Personal Microsoft accounts are not supported for this application unless explicitly invited to an organization. Try signing out and signing back in with an organizational account. A personal Microsoft account (for example Outlook.com, or a Gmail address used as a Microsoft account) tried to sign in to an app that only accepts work or school accounts. The message itself names two ways out: an invitation to the organization, or a work account. A Microsoft employee answering in the [first thread](https://learn.microsoft.com/en-us/answers/questions/1059353/aadsts500200-user-account-is-a-personal-microsoft) gives the cause as the app's supported account type: *"If your app registration is set to a single-tenant account type, users from other directories or identity providers can't sign into that application."* He says to make sure the user *"was invited to your Azure AD tenant, or that the App you're trying to sign into allows `AzureADandPersonalMicrosoftAccount`."* That matches what Microsoft documents about account types. An app registration's `signInAudience` decides who can sign in. Microsoft's [supported account types page](https://learn.microsoft.com/entra/identity-platform/supported-accounts-validation) lists four values: | `signInAudience` | Label in the app registration | |---|---| | `AzureADMyOrg` | Accounts in this organizational directory only (Single tenant) | | `AzureADMultipleOrgs` | Accounts in any organizational directory (Multitenant) | | `AzureADandPersonalMicrosoftAccount` | Accounts in any organizational directory and personal Microsoft accounts (such as Skype, Xbox) | | `PersonalMicrosoftAccount` | Personal Microsoft accounts only | Only the last two take a personal account that hasn't been invited. The authority the app signs in through matters too. Microsoft's MSAL configuration page says `/organizations` signs in *"users with work and school accounts"*, a tenant-specific authority signs in *"users of a specific organization only"*, and only `/common` and `/consumers` take personal accounts. Our reading: an app on `/organizations` or a tenant authority gets this error for a personal account even when the registration allows personal accounts. We have not tested that. ## Is it an attack? No. It is an account-type mismatch. The account is real, but the app doesn't accept that kind of account. | Pattern | Likely meaning | |---|---| | One person, a consumer address (outlook.com, gmail.com) | They used a personal account where a work account is needed. Benign. | | Users report it on Microsoft 365 apps on a phone while editing their own documents | In the [second thread](https://learn.microsoft.com/en-us/answers/questions/1476251/how-to-fix-error-aadsts500200-user-account-is-a-pe), one user with a Microsoft 365 Family account gets it when editing on Android, and another only in the OneNote Android app. Likely the app was routed to a work-account sign-in, but that is unconfirmed. Not something an admin can fix. | | Users report it on the Microsoft Learn sandbox | Same thread. The sandbox needs a work account in a tenant. | | An external partner using a personal address, hitting one of your apps | They were never invited as a guest. Invite them if they need access. | | A developer's own app, right after registration | The registration is single tenant or multitenant without personal accounts. | We found no source that links 500200 to an attack pattern. The sign-in fails before any of your resources are reached. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 500200 is logged in, or whether it is logged in your tenant at all. Our reading: a personal account that was never invited has no user object in your tenant, so a row may not appear there. Check first: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "500200" | summarize Rows = count() by SourceTable ``` If rows exist, see which apps and which home tenants they come from. `HomeTenantId` is documented as *"the tenant identifier of the user initiating the sign in"*: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "500200" | summarize Attempts = count(), Users = dcount(UserPrincipalName), Sample = make_set(UserPrincipalName, 10) by AppDisplayName, AppId, HomeTenantId | sort by Attempts desc ``` ## How do I fix AADSTS500200? **For the user:** sign out and sign in again with your work or school account, as the message says. If you don't have one for this organization, ask its admin to invite you. Volunteer moderators on Q&A suggest trying a private browser window first, in case the browser keeps signing you in with the personal account. One user in the second thread says that didn't help. **For developers:** 1. Check **Supported account types** in the app registration, or `signInAudience` in the manifest. If personal accounts must work, use `AzureADandPersonalMicrosoftAccount`. Microsoft warns: *"If you change this property you may need to change other properties first."* Personal-account audiences have extra limits, for example no national clouds and at most two client secrets. 2. Sign in through `/common` (work and personal accounts) or `/consumers` (personal only). `/organizations` and a tenant ID only take work and school accounts. 3. In a comment on the first Q&A thread, one user reports the error with `signInAudience` set to `AzureADandPersonalMicrosoftAccount` and `accessTokenAcceptedVersion` set to 2, on an Azure App Service site. Nobody replied to that comment. If you hit the same, check the authority in the app's configuration (point 2), which is our best guess, not a confirmed cause. **For admins:** 1. If the person needs access to your app, invite them as a guest. Microsoft says B2B guests *"can use their own personal Microsoft accounts for B2B collaboration without further configuration."* 2. If the app is a third-party product that should accept personal accounts, that is the vendor's registration to change, not yours. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft Q&A: AADSTS500200: User account is a personal Microsoft account](https://learn.microsoft.com/en-us/answers/questions/1059353/aadsts500200-user-account-is-a-personal-microsoft) 3. [Microsoft Q&A: How to fix error AADSTS500200](https://learn.microsoft.com/en-us/answers/questions/1476251/how-to-fix-error-aadsts500200-user-account-is-a-pe) 4. [Validation differences by supported account types (signInAudience)](https://learn.microsoft.com/entra/identity-platform/supported-accounts-validation) 5. [Client application configuration (MSAL)](https://learn.microsoft.com/en-us/entra/identity-platform/msal-client-application-configuration) 6. [Use Microsoft accounts (MSA) for B2B collaboration](https://learn.microsoft.com/entra/external-id/microsoft-account) 7. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS90072](https://brambrinkmeier.com/entra/aadsts/90072/), [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS500200: Personal Microsoft account not supported by this app (fix)", https://brambrinkmeier.com/entra/aadsts/500200/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/500341/ # AADSTS500341: User account has been deleted from the directory (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/500341/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/500341.json **Short answer:** AADSTS500341 means the account signing in has been deleted from the Microsoft Entra tenant. Microsoft's error reference doesn't list it; a Microsoft Viva Goals page does. Something still uses the old account: a saved sign-in, a connection or a script. Restore the user within 30 days if the deletion was a mistake, otherwise reconnect with an active account. **Fix:** Admin: if the deletion was a mistake, restore the user within 30 days (Entra ID > Users > Deleted users). If it was intended, reconnect each integration that still uses the account with an active account. User: ask IT whether the removal was intended, or sign in with your new account. | Field | Value | |---|---| | Code | AADSTS500341 | | Category | Credentials and lockout | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS500341 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS500341 (checked 30 October 2026). Microsoft documents it on a [Viva Goals page about Microsoft Entra errors](https://learn.microsoft.com/en-gb/viva/goals/integration-aad-errors), which gives the message as: > AADSTS500341: The user account <account ID> has been deleted from the <AAD> directory. To sign into this application, the account must be added to the directory Its resolution: *"The user account with which this connection was first created is no longer in an active state. Try creating a new connection."* The same page lists [50034](https://brambrinkmeier.com/entra/aadsts/50034/) as *"The user account <account ID> doesn't exist in the <AAD> directory."* So the two codes say different things: 50034 is a name that doesn't exist, 500341 an account that existed and was deleted. Microsoft's page on restoring users explains the deleted state: *"After you delete a user, the account remains in a suspended state for 30 days. During that 30-day window, the user account can be restored, along with all its properties."* After that, *"the permanent deletion process automatically starts and can't be stopped."* Microsoft doesn't say whether 500341 is returned only during those 30 days or also after permanent deletion. We tried to reproduce it in the lab three times on 30 October 2026 and never got 500341. What we got instead is worth knowing: | Time between deleting the user and signing in | Result | |---|---| | About 30 seconds | [65001](https://brambrinkmeier.com/entra/aadsts/65001/), consent not granted: the same answer an active user got in that run | | About 30 seconds, with consent already granted | **A token was issued.** The sign-in succeeded for a user that no longer existed | | About 12 minutes | [50034](https://brambrinkmeier.com/entra/aadsts/50034/), the user account does not exist | The middle row is the one to take away: a deleted account can still sign in successfully for a short window after deletion. That is a reason to revoke sessions and disable the account before you delete it, rather than relying on the delete alone. None of the three runs produced 500341, so on this tenant a deleted user ends up at 50034 instead. Microsoft's Viva Goals page gives both codes the same resolution, and we can't tell from here which conditions produce which. The lab tenant's exported sign-in log shows the first attempt in `SigninLogs` under the deleted user's name, as 65001 with status Interrupted. ## Is it an attack? Usually not. It means something still uses an account you deleted. | Pattern | Likely meaning | |---|---| | A connection or integration stops working after an offboarding | It was set up with the deleted user's account, as Microsoft's Viva Goals page describes. Reconnect it with an active account. | | One device or app keeps failing for a departed employee | A saved sign-in or a mail profile on a device that wasn't wiped. Benign, but find the device. | | A user deleted by mistake who suddenly can't sign in | Restore them within 30 days. | | Attempts on a deleted account from IP addresses the person never used | Someone else has the old credentials. The sign-in fails, but check where else those credentials work, for example other accounts with the same password. Our interpretation, not a documented pattern. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 500341 is logged in. Check where it lands: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "500341" | summarize Rows = count() by SourceTable ``` Which deleted accounts are still being used, from where and by what: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "500341" | summarize Attempts = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), IPs = make_set(IPAddress, 10), Apps = make_set(AppDisplayName, 10), Agents = make_set(UserAgent, 5) by UserPrincipalName, UserId | sort by Attempts desc ``` Sign-ins for an account after it was deleted, whatever the result. `Delete user` is an activity name in Microsoft's audit activity list. This joins on the object ID; whether `UserId` is still filled for a deleted account is our assumption, not checked: ```kusto let deletions = AuditLogs | where TimeGenerated > ago(30d) | where ActivityDisplayName == "Delete user" | extend UserId = tostring(TargetResources[0].id), DeletedBy = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)) | project DeletedAt = TimeGenerated, UserId, DeletedBy; union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | join kind=inner deletions on UserId | where TimeGenerated > DeletedAt | summarize Attempts = count(), Results = make_set(ResultType, 10), LastSeen = max(TimeGenerated) by UserPrincipalName, UserId, DeletedAt, DeletedBy | sort by LastSeen desc ``` A `"0"` in `Results` means a sign-in succeeded after the deletion was logged. The lab run above didn't show that: it got 65001, not a success. Look at how long after `DeletedAt` it happened before treating it as a problem. ## How do I fix AADSTS500341? **For the user:** your account was removed from the organization. Ask its IT team whether that was intended. If you moved to a new account, sign out of the app and sign in with the new one. **For developers:** treat 500341 as "this account is gone". Clear the cached account and send the user through an interactive sign-in instead of retrying the same account. **For admins:** 1. Deleted by mistake: restore the user within 30 days. In the Microsoft Entra admin center, as at least a User Administrator, go to **Entra ID** > **Users** > **Deleted users**. Microsoft says restoring brings back the account's properties and the licenses it had. 2. For a synced user, Microsoft warns that *"if the user still exists in your on-premises directory, the sync engine may restore the user during the next synchronization cycle."* Fix the source object first if the deletion was intended. 3. Deleted on purpose: find what still uses the account with the second query, and reconnect each integration with an active account, as the Viva Goals page says. 4. Unknown IP addresses on a deleted account: treat the old password as known to someone else. If the same person has another account, reset its password and revoke its sessions. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. Lab-run rows naming this code (15; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Deleted user signs in | 500341 / 50034 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-30 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-30 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-30 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-30 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-30 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-30 | Deleted user signs in | 500341 / 50034 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-signin-client'. Send a | | 2026-10-31 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-31 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | | 2026-10-31 | Deleted user signs in | 500341 / 50034 | success | | | 2026-10-31 | Deleted user signs in, about 12 minutes after deletion | 500341 / 50034 | 50034 | AADSTS50034: The user account {EUII Hidden} does not exist in the {tenant-id} directory. To sign into this application, the account mus | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft Entra ID errors (Viva Goals integrations)](https://learn.microsoft.com/en-gb/viva/goals/integration-aad-errors) 3. [Restore or remove a recently deleted user](https://learn.microsoft.com/entra/fundamentals/users-restore) 4. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/), [AADSTS50057](https://brambrinkmeier.com/entra/aadsts/50057/), [AADSTS50173](https://brambrinkmeier.com/entra/aadsts/50173/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS500341: User account has been deleted from the directory (fix)", https://brambrinkmeier.com/entra/aadsts/500341/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/500571/ # AADSTS500571: The guest user account is disabled (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/500571/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/500571.json **Short answer:** AADSTS500571 means a guest (B2B) user tried to sign in to an app in a tenant where their guest account is disabled. Microsoft's error reference doesn't list it, but a Microsoft troubleshooting article does. Their home account can be fine. It has low attack value. The resource tenant decides: leave it blocked, or re-enable the guest object. **Fix:** Guest user: contact whoever invited you to the other organization, or its IT; your own IT can't fix this. Resource tenant admin: if the guest was disabled by mistake, re-enable the guest object (accountEnabled = true, for example with Update-MgUser). If on purpose, do nothing. | Field | Value | |---|---| | Code | AADSTS500571 | | Category | Guests and tenants | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS500571 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS500571 (checked 30 October 2026). Microsoft documents it in a [troubleshooting article](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts500571-guest-user-account-is-disabled): > When a guest user tries to sign in to an application that's integrated into Microsoft Entra ID, they receive an "AADSTS500571" error message ("The guest user account is disabled"). The cause, in Microsoft's words: *"The guest user object is disabled on the resource tenant."* A user posting on Microsoft Tech Community quotes the full string as returned to Visual Studio: > V2Error: invalid_grant AADSTS500571: The guest user account is disabled Background: when you invite a guest, Microsoft says *"an account is created in your tenant. This account doesn't have any credentials associated with it because authentication is performed by the guest user's identity provider."* So there are two accounts. The one in the user's home tenant can be enabled and working while the guest object in the resource tenant is disabled. 500571 is about the second one. If the account in the user's own tenant were disabled, that would be [50057](https://brambrinkmeier.com/entra/aadsts/50057/). ## Is it an attack? Usually not. A disabled guest object is a deliberate block by the resource tenant, or a mistake. | Pattern | Likely meaning | |---|---| | A partner user who was offboarded or whose project ended | The guest was disabled on purpose. Access is blocked as intended. | | Many guests from one partner disabled on the same day | A bulk clean-up, an access review, or a script. Check the audit log for who did it. | | A user who says *"I'm not a guest, I signed in with my own account"* | An admin on Q&A reports this for a Teams user who said he signed in with his own account. Our reading: the app tried to reach another tenant where the user has a disabled guest object, for example a tenant switch in Teams or a link from a partner. | | Repeated 500571 for a guest who was disabled during an incident | Something still holds that person's sign-in and keeps trying. Worth a look. Our interpretation, not a documented pattern. | Our reading: the block works. A failed sign-in with 500571 means no token was issued for that guest in your tenant. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 500571 is logged in. Check where it lands: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "500571" | summarize Rows = count() by SourceTable ``` Which guests, from which home tenants, on which apps. `HomeTenantId` is documented as *"the tenant identifier of the user initiating the sign in"* and `UserType` as identifying *"whether the user is a member or guest in the tenant"*: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "500571" | summarize Attempts = count(), LastSeen = max(TimeGenerated), Apps = make_set(AppDisplayName, 10) by UserPrincipalName, UserId, HomeTenantId, UserType | sort by Attempts desc ``` Who disabled the guest, and when. `Disable account` and `Update user` are both activity names in Microsoft's audit activity list. Which one a disable produces depends on how it was done, so search for both: ```kusto AuditLogs | where TimeGenerated > ago(90d) | where ActivityDisplayName in ("Disable account", "Update user") | extend TargetUpn = tostring(TargetResources[0].userPrincipalName), TargetId = tostring(TargetResources[0].id), Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)) | where TargetUpn has "#EXT#" or TargetId == "" | project TimeGenerated, ActivityDisplayName, Actor, TargetUpn, TargetId, Result | sort by TimeGenerated desc ``` The `#EXT#` filter is a shortcut for guest UPNs. Microsoft's B2B user properties page says a guest's UPN contains `#EXT#`. Put the `UserId` from the second query in place of `` to be exact. `Update user` also covers changes that have nothing to do with sign-in, so read the modified properties in `TargetResources` before drawing a conclusion. ## How do I fix AADSTS500571? **For the user:** your own organization can't fix this. The block is in the other organization's tenant. Contact whoever invited you there, or their IT. Microsoft says to *"engage the resource tenant owners or sponsor."* **For admins of the resource tenant:** find out why the guest was disabled, then follow Microsoft's two cases: | Case | Microsoft's action | |---|---| | The guest is supposed to be disabled | *"No actions should be performed. Access is expectedly blocked."* | | It was disabled by mistake | *"Resource tenant owners should re-enable the account."* | To re-enable the guest with Microsoft Graph PowerShell, set `accountEnabled` to true. This is the command from Microsoft's page on blocking accounts with PowerShell; `-UserId` takes the UPN or object ID: ```powershell Connect-Graph -Scopes User.ReadWrite.All $params = @{ accountEnabled = $true } Update-MgUser -UserId "" -BodyParameter $params ``` Microsoft's troubleshooting article points to `Set-AzureADUser` with `-AccountEnabled $true`, from the AzureAD module. Both set the same `accountEnabled` property, as far as we can tell. **For admins of the user's home tenant:** nothing to change on your side. Check that the user is trying to reach the tenant they think they are. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Error AADSTS500571 - Guest user account is disabled](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts500571-guest-user-account-is-disabled) 3. [Properties of a Microsoft Entra B2B collaboration user](https://learn.microsoft.com/entra/external-id/user-properties) 4. [Microsoft Tech Community: AADSTS500571 in Visual Studio to Azure Resource Manager](https://techcommunity.microsoft.com/discussions/microsoft-entra/aadsts500571-in-visual-studio-to-azure-resource-manager-guest-account-disabled-i/4562088) 5. [Microsoft Q&A: Microsoft Teams Failure (500571)](https://learn.microsoft.com/en-us/answers/questions/1431608/microsoft-teams-failure) 6. [Block Microsoft 365 user accounts with PowerShell](https://learn.microsoft.com/en-us/microsoft-365/enterprise/block-user-accounts-with-microsoft-365-powershell?view=o365-worldwide) 7. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) 8. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50057](https://brambrinkmeier.com/entra/aadsts/50057/), [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS90072](https://brambrinkmeier.com/entra/aadsts/90072/), [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS500571: The guest user account is disabled (fix)", https://brambrinkmeier.com/entra/aadsts/500571/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/501051/ # AADSTS501051: Client app isn't assigned to a role for the API (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/501051/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/501051.json **Short answer:** AADSTS501051 means a client app asked for an access token to a web API whose enterprise app has "Assignment required" set to Yes, and the client holds no app role on that API. Microsoft's error reference doesn't list it, but its protected web API docs do. Low attack value. Assign an app role to the client; don't switch assignment off. **Fix:** Admin: assign the client an app role on the API, by granting consent for the role it requested or with New-MgServicePrincipalAppRoleAssignment. Don't set Assignment required back to No. Developer: expose an app role for Applications and request it under API permissions. | Field | Value | |---|---| | Code | AADSTS501051 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS501051 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS501051 (checked 30 October 2026). Microsoft does document it on another page. Its protected web API guide explains how to restrict token issuance to approved client apps, by setting **Assignment required?** to **Yes** on the API's enterprise application. Then: > Microsoft Entra ID will now check for app role assignments of client applications that request access tokens for your web API. If a client app hasn't been assigned any app roles, Microsoft Entra ID returns an error message to the client similar to `invalid_client: AADSTS501051: Application isn't assigned to a role for the `. So two things are true at once: 1. The API's enterprise application (its service principal) has **Assignment required?** set to **Yes**. 2. The client app that asked for the token has no app role on that API. Microsoft's enterprise app properties page describes the switch: *"If this option is set to **Yes**, then users and other applications or services must first be assigned this application before being able to access it."* It applies to *"Applications or services for which other applications or service are requesting access tokens."* Our reading: 501051 is the app-side twin of [50105](https://brambrinkmeier.com/entra/aadsts/50105/). 50105 is a user without an assignment. 501051 is a client app without one. Microsoft doesn't say so in those words. ## Is it an attack? Usually not. It is the assignment check doing what it was set up to do. | Pattern | Likely meaning | |---|---| | A new daemon or service fails on its first token request | Nobody assigned it an app role on the API yet. | | A working client starts failing after a change | Someone turned on **Assignment required?** on the API, or removed the client's app role assignment. Check the audit log. | | A client you don't recognise hits 501051 against an internal API | Possibly a client with valid credentials trying an API it was never granted (see below). Find out who owns that client. | | Repeated 501051 from one client, every few minutes | A scheduled job retrying with no fix in sight. Noise until someone assigns the role. | Microsoft doesn't document this, but the role check probably runs after the client has authenticated, so a 501051 from an unknown client may mean it holds working credentials in your tenant. That deserves a look, even though no token was issued. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 501051 is logged in. App-only requests (client credentials) probably land in `AADServicePrincipalSignInLogs`. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "501051" | summarize Rows = count() by SourceTable ``` Which clients are refused, and for which API: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "501051" | summarize Rows = count(), IPs = make_set(IPAddress, 10), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by ServicePrincipalName, AppId, ResourceDisplayName, ResourceIdentity | sort by Rows desc ``` Service principal sign-in rows are aggregated, so `Rows` is not a request count. Who changed assignments. Microsoft's audit log reference lists **Add app role assignment to service principal**, **Remove app role assignment from service principal** and **Update service principal** in the ApplicationManagement category: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where Category == "ApplicationManagement" | where OperationName in ("Add app role assignment to service principal", "Remove app role assignment from service principal", "Update service principal") | project TimeGenerated, OperationName, Target = tostring(TargetResources[0].displayName), ByUser = tostring(InitiatedBy.user.userPrincipalName), ByApp = tostring(InitiatedBy.app.displayName) | sort by TimeGenerated desc ``` Our assumption: turning **Assignment required?** on or off is logged as **Update service principal**. Microsoft's reference lists the activity but not which property changes it covers. ## How do I fix AADSTS501051? **For the user:** this error is between two apps, not about your account. Report it to whoever runs the app. **For developers:** 1. Make sure the API exposes an app role for applications. Microsoft's guide: in **Create app role**, under **Allowed member types**, select **Applications**. 2. Request the role in the client's app registration: **API permissions** > **Add a permission** > **My APIs** > your API > the role. 3. Get an admin to grant consent. Microsoft: *"Because these are application permissions, not delegated permissions, an admin must grant consent to use the app roles assigned to the application."* 4. Don't branch on the AADSTS code in your code. Microsoft warns that the codes and message strings *"may be changed by Microsoft at any time and without your knowledge."* **For admins:** 1. Don't fix this by setting **Assignment required?** back to **No**. That opens the API to every client in the tenant again. 2. Grant consent for the app role the client requested, or assign the role directly with Microsoft Graph PowerShell. `-ServicePrincipalId` and `principalId` are the client's service principal. `resourceId` is the API's service principal: ```powershell Connect-MgGraph -Scopes "AppRoleAssignment.ReadWrite.All" $client = Get-MgServicePrincipal -Filter "appId eq ''" $api = Get-MgServicePrincipal -Filter "appId eq ''" $params = @{ principalId = $client.Id resourceId = $api.Id appRoleId = "" } New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $client.Id -BodyParameter $params ``` 3. If the API defines no app roles, Microsoft's cmdlet reference says a default ID of `00000000-0000-0000-0000-000000000000` *"can be specified to signal that the principal is assigned to the resource app without any specific app roles."* Our reading: a dedicated app role is the better choice, because the API can then check the `roles` claim. 4. If the client is one you don't recognise, don't assign anything. Find its owner first. ## Evidence Reproduced in a lab tenant on 2026-10-30 (token-endpoint requests against a lab tenant; scenario: App-only token for an API that requires assignment). First line returned: > AADSTS501051: Application '{app-id}'(lab-fic-holder) is not assigned to a role for the application Lab-run rows naming this code (3; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | App-only token for an API that requires assignment | 501051 | 501051 | AADSTS501051: Application '{app-id}'(lab-fic-holder-41143330001) is not assigned to a role for the application 'api://{guid} | | 2026-10-31 | App-only token for an API that requires assignment | 501051 | 501051 | AADSTS501051: Application '{app-id}'(lab-fic-holder-41146039117) is not assigned to a role for the application 'api://{guid} | | 2026-10-31 | App-only token for an API that requires assignment | 501051 | 501051 | AADSTS501051: Application '{app-id}'(lab-fic-holder-41150019626) is not assigned to a role for the application 'api://{guid} | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Protected web API: App registration and scopes](https://learn.microsoft.com/entra/identity-platform/scenario-protected-web-api-expose-scopes) 3. [Properties of an enterprise application](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/application-properties) 4. [Add app roles to your application and receive them in the token](https://learn.microsoft.com/en-us/entra/identity-platform/howto-add-app-roles-in-apps) 5. [New-MgServicePrincipalAppRoleAssignment (Microsoft Graph PowerShell)](https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.applications/new-mgserviceprincipalapproleassignment) 6. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) 7. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS50105](https://brambrinkmeier.com/entra/aadsts/50105/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS7000112](https://brambrinkmeier.com/entra/aadsts/7000112/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS501051: Client app isn't assigned to a role for the API (fix)", https://brambrinkmeier.com/entra/aadsts/501051/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/530002/ # AADSTS530002: Your device is required to be compliant (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/530002/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/530002.json **Short answer:** AADSTS530002 means a Conditional Access policy requires a compliant device and the device isn't compliant. Microsoft's error reference doesn't list it; a Viva Goals troubleshooting page does, for stored connections whose device fell out of compliance. Most user reports of compliant-device blocks quote the listed code 53000 instead. Usually benign drift out of compliance. **Fix:** User: open Company Portal (or your MDM app), fix what it reports, sync, and sign in again. For a stopped integration, reauthenticate or recreate the connection on a compliant device. Admin: find the policy in the sign-in log, then check in Intune which compliance setting fails. | Field | Value | |---|---| | Code | AADSTS530002 | | Category | Devices | | Type | Failure | | Attack signal | Medium: worth a look in context | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS530002 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS530002 (checked 30 October 2026). Microsoft documents it on another page. The Viva Goals troubleshooting page for integration errors lists it under the heading *"AADSTS530002: Your device is required to be compliant to access this resource"* and says: > The device on which this connection was first created is no longer in a compliant state. Try reauthenticating or creating a new connection. That page introduces its list as errors you get *"if you encounter an AAD invalid grant error for an integration"*. So the scenario Microsoft describes is a connection created on a device that was compliant at the time, whose token later fails because the device no longer is. We found little else. Two web searches for the exact message returned no user thread that quotes 530002. The Q&A and community threads they returned all quote the listed code [53000](https://brambrinkmeier.com/entra/aadsts/53000/) instead, for example: *"AADSTS53000: Device is not in required device state: compliant. Conditional Access policy requires a compliant device, and the device is not compliant."* Our reading: 530002 and 53000 come from the same grant control, **Require device to be marked as compliant**. 53000 is the code people see at sign-in. 530002 shows up, as far as Microsoft's one page says, when a stored grant is used later. Microsoft doesn't document how the two differ, so fix both the same way. ## Is it an attack? Usually not. The common cause is a device that drifted out of compliance: an overdue OS update, a disabled disk encryption setting, or a lapsed Intune check-in. | Pattern | Likely meaning | |---|---| | 530002 for an integration or background sync that worked before | The device the connection was created on is no longer compliant. Microsoft's Viva Goals scenario. | | 530002 for many users on the same day | A compliance policy changed in Intune and many devices fell out of compliance at once. Likely, but unconfirmed. | | 530002 for one user on a device with an empty device ID | The device isn't registered, so it can't be compliant. Microsoft says devices *"must be registered in Microsoft Entra ID before they can be marked as compliant."* | | 530002 for a privileged account from a new IP or country | Our reasoning: a working session or token is being used from a device you don't manage. Check whether it was the user. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 530002 is logged in. The Viva Goals scenario (a refreshed integration token) points to `AADNonInteractiveUserSignInLogs` as the likely place, but check: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType in ("530002", "53000") | summarize Rows = count() by SourceTable, ResultType ``` Which devices fail, and what compliance state the sign-in recorded. `DeviceDetail` is dynamic in `SigninLogs` and a string in `AADNonInteractiveUserSignInLogs`, so each leg parses it first. The property names come from the Graph `deviceDetail` resource: ```kusto let rows = union (SigninLogs | extend D = parse_json(tostring(DeviceDetail)) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, IPAddress, D), (AADNonInteractiveUserSignInLogs | extend D = parse_json(DeviceDetail) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, IPAddress, D); rows | where TimeGenerated > ago(7d) | where ResultType == "530002" | extend DeviceId = tostring(D.deviceId), DeviceName = tostring(D.displayName), IsCompliant = tostring(D.isCompliant), TrustType = tostring(D.trustType), OS = tostring(D.operatingSystem) | summarize Rows = count(), Users = make_set(UserPrincipalName, 10), Apps = make_set(AppDisplayName, 10), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by DeviceId, DeviceName, IsCompliant, TrustType, OS | sort by Rows desc ``` A day with many more devices failing than usual. The factor of 3 is a starting point: ```kusto let daily = union (SigninLogs | extend DeviceId = tostring(DeviceDetail.deviceId) | project TimeGenerated, ResultType, DeviceId), (AADNonInteractiveUserSignInLogs | extend DeviceId = tostring(parse_json(DeviceDetail).deviceId) | project TimeGenerated, ResultType, DeviceId) | where TimeGenerated > ago(30d) | where ResultType in ("530002", "53000") | summarize Devices = dcount(DeviceId) by Day = bin(TimeGenerated, 1d); let baseline = toscalar(daily | summarize avg(Devices)); daily | where Devices > 3 * baseline | sort by Day asc ``` ## How does Conditional Access affect it? - The control is **Require device to be marked as compliant**. Microsoft says it *"only supports Windows 10+, iOS, Android, macOS, and Linux Ubuntu devices registered with Microsoft Entra ID and enrolled with Intune"*, and that *"Microsoft Edge in InPrivate mode on Windows is considered as a noncompliant device."* - Compliance comes from Intune or a supported non-Microsoft MDM: *"Intune sends compliance information to Microsoft Entra ID so Conditional Access can decide to grant or block access to resources."* So the fix is usually in Intune, not in Conditional Access. - By default a policy with several controls requires all of them. With "require one of", hybrid join or MFA can stand in for compliance. - For guest users, see [530004](https://brambrinkmeier.com/entra/aadsts/530004/): the resource tenant has to trust the home tenant's compliance claim. ## How do I fix AADSTS530002? **For the user:** open Company Portal (or your MDM app) on the device, check what it says is wrong, fix it, and sync. Then sign in again. For an integration that stopped working, the Viva Goals advice is to reauthenticate or create the connection again, on a compliant device. **For admins:** 1. Open the failed sign-in in **Entra ID** > **Monitoring & health** > **Sign-in logs**. The **Conditional Access** tab names the policy; Microsoft says the **Troubleshooting and support** tab may show the reason, *"such as a device that didn't meet compliance requirements."* 2. Look the device up in Intune and read which compliance setting fails. 3. If the second query shows an empty device ID, the device isn't registered. Register or enroll it first. 4. If many devices failed on one day, review the last change to your compliance policies before you touch Conditional Access. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Troubleshoot AAD errors for integrations (Viva Goals)](https://learn.microsoft.com/en-gb/viva/goals/integration-aad-errors) 3. [Graph API token generation failed: device is not in required state (Microsoft Q&A 2122577)](https://learn.microsoft.com/en-sg/answers/questions/2122577/graph-api-token-generation-failed-device-is-not-in) 4. [Conditional Access: Grant](https://learn.microsoft.com/en-gb/entra/identity/conditional-access/concept-conditional-access-grant) 5. [Troubleshoot sign-in problems with Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/troubleshoot-conditional-access) 6. [deviceDetail resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/devicedetail) 7. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 8. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/AADNonInteractiveUserSignInLogs) ## Related codes [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS50097](https://brambrinkmeier.com/entra/aadsts/50097/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS530003](https://brambrinkmeier.com/entra/aadsts/530003/), [AADSTS530004](https://brambrinkmeier.com/entra/aadsts/530004/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS530002: Your device is required to be compliant (fix)", https://brambrinkmeier.com/entra/aadsts/530002/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/530003/ # AADSTS530003: Your device is required to be managed (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/530003/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/530003.json **Short answer:** AADSTS530003 means a Conditional Access policy requires a managed device and the device asking for the token isn't one, or can't prove it. Microsoft's error reference doesn't list it. Users report it from the Azure CLI, Terraform and Cloud Shell. Usually it is a tool on an unmanaged machine. From a new device or IP, check whether the account is in the right hands. **Fix:** User: run the tool on your managed work device, or sign in with a browser there. For automation, use a service principal or managed identity, not a user account. Admin: find the policy on the failed sign-in's Conditional Access tab and decide whether it should cover that app. | Field | Value | |---|---| | Code | AADSTS530003 | | Category | Devices | | Type | Failure | | Attack signal | Medium: worth a look in context | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS530003 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS530003 (checked 30 October 2026). Microsoft documents it on another page. The Viva Goals troubleshooting page for integration errors lists it under the heading *"AADSTS530003: Your device is required to be managed to access this resource"* and says: > The device on which this connection was first created might not have been in a managed state. Try reauthenticating or creating a new connection. That page introduces its list as errors you get *"if you encounter an AAD invalid grant error for an integration"*, so it covers a stored connection whose token is refreshed later. Users report the same message from command-line tools. On HashiCorp Discuss, `terraform plan` on Ubuntu with the azurerm provider failed while reading a token from the Azure CLI: > ERROR: AADSTS530003: Your device is required to be managed to access this resource. On Microsoft Q&A, `az account get-access-token --resource https://graph.microsoft.com` in Azure Cloud Shell returned the same text. Neither thread has an answer. Our reading: a Conditional Access policy requires a managed device (compliant or hybrid joined), and the device asking for the token is not one or can't prove it. Microsoft doesn't publish a name or a precise definition for 530003. The listed codes for the same family are [53000](https://brambrinkmeier.com/entra/aadsts/53000/) (device not compliant) and [53001](https://brambrinkmeier.com/entra/aadsts/53001/) (device not domain joined). ## Is it an attack? Usually not. Most reports come from tools that can't present a device identity: a CLI on Linux, a container, Cloud Shell, or a stored integration. | Pattern | Likely meaning | |---|---| | 530003 from Azure CLI, Terraform or PowerShell on a build agent or Linux machine | The tool runs on a machine that isn't managed by the tenant. Expected under a managed-device policy. | | 530003 right after `az login --use-device-code` | Microsoft says device code flow can't carry device state (see below), so expect it under a managed-device policy. | | 530003 from Cloud Shell | Probably because Cloud Shell runs on a Microsoft host, not on the user's device. Unconfirmed; based on one Q&A report. | | 530003 for a privileged account from a new IP or country | Our reasoning: the account got far enough for a device control to apply. Check whether the sign-in was the user. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 530003 is logged in. Check where it lands first: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "530003" | summarize Rows = count() by SourceTable ``` Which users, apps and device states hit it. `DeviceDetail` is dynamic in `SigninLogs` and a string in `AADNonInteractiveUserSignInLogs`, so each leg parses it before the union. The property names come from the Graph `deviceDetail` resource: ```kusto let rows = union (SigninLogs | extend D = parse_json(tostring(DeviceDetail)) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, ClientAppUsed, UserAgent, IPAddress, D), (AADNonInteractiveUserSignInLogs | extend D = parse_json(DeviceDetail) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, ClientAppUsed, UserAgent, IPAddress, D); rows | where TimeGenerated > ago(7d) | where ResultType == "530003" | extend DeviceId = tostring(D.deviceId), TrustType = tostring(D.trustType), IsManaged = tostring(D.isManaged), IsCompliant = tostring(D.isCompliant), OS = tostring(D.operatingSystem) | summarize Rows = count(), IPs = make_set(IPAddress, 10), Agents = make_set(UserAgent, 5) by UserPrincipalName, AppDisplayName, ClientAppUsed, DeviceId, TrustType, IsManaged, IsCompliant, OS | extend Unregistered = isempty(DeviceId) | sort by Rows desc ``` 530003 from an IP where the same user had no successful sign-in in the last 30 days. A starting point for triage, not a detection rule: ```kusto let lookback = 30d; let knownUserIPs = union (SigninLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType), (AADNonInteractiveUserSignInLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType) | where TimeGenerated > ago(lookback) | where ResultType == "0" | distinct UserPrincipalName, IPAddress; union (SigninLogs | project TimeGenerated, ResultType, UserPrincipalName, IPAddress, AppDisplayName, UserAgent), (AADNonInteractiveUserSignInLogs | project TimeGenerated, ResultType, UserPrincipalName, IPAddress, AppDisplayName, UserAgent) | where TimeGenerated > ago(1d) | where ResultType == "530003" | join kind=leftanti knownUserIPs on UserPrincipalName, IPAddress | sort by TimeGenerated desc ``` ## How does Conditional Access affect it? - 530003 most likely comes from a device grant control: **Require device to be marked as compliant**, **Require Microsoft Entra hybrid joined device**, or both. The Conditional Access tab on the failed sign-in shows which policy applied. - Microsoft says device code flow can't satisfy these controls: *"When you use the device-code OAuth flow, the required grant control for the managed device or a device state condition isn't supported. This is because the device that is performing authentication can't provide its device state to the device that is providing a code."* Microsoft's advice there: use **Require multifactor authentication** instead. - Microsoft also says Edge in InPrivate mode doesn't count as compliant or hybrid joined. - By default, a policy with several controls requires all of them. With "require one of the selected controls", MFA can stand in for the device. ## How do I fix AADSTS530003? **For the user:** run the tool on your managed work device, or sign in with a browser on that device. If you need the tool somewhere else, such as a build server, ask IT how they want that done. **For developers:** Microsoft's MSAL.NET page on device authentication says the device must prove its identity, and *"to satisfy this requirement you will have to leverage WAM on Windows or the system browser. On mobile platforms, you'll need to enable the brokers (Microsoft Authenticator and Company portal)."* An embedded web view or a plain HTTP client can't do that. For automation, don't use a user account at all. Use a service principal or managed identity. Our reading is that user device-state controls don't apply to those, but check your own policies. **For admins:** 1. Open the failed sign-in in **Entra ID** > **Monitoring & health** > **Sign-in logs** and select the **Conditional Access** tab. It names the policy. Microsoft adds that the **Troubleshooting and support** tab may show the reason directly. 2. Check the device in the second query. An empty `DeviceId` means the device isn't registered, so it can't be managed. 3. Decide whether the policy should cover that app. If admins need Azure CLI from unmanaged machines, scope an exception for those users or allow MFA as an alternative. Use the What If tool before you change a production policy. 4. If the device should be managed, enroll or join it and sign in again. The Viva Goals page gives the same advice for stored connections: reauthenticate or create a new connection. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Troubleshoot AAD errors for integrations (Viva Goals)](https://learn.microsoft.com/en-gb/viva/goals/integration-aad-errors) 3. [Error: AADSTS530003 (HashiCorp Discuss)](https://discuss.hashicorp.com/t/error-aadsts530003-your-device-is-required-to-be-managed-to-access-this-resource/58943) 4. [Get access token against microsoft graph failing (Microsoft Q&A 1441736)](https://learn.microsoft.com/en-us/answers/questions/1441736/get-access-token-against-microsoft-graph-failing) 5. [Conditional Access: Grant](https://learn.microsoft.com/en-gb/entra/identity/conditional-access/concept-conditional-access-grant) 6. [Device authentication errors (MSAL.NET)](https://learn.microsoft.com/en-us/entra/msal/dotnet/advanced/exceptions/device-authentication-errors) 7. [Troubleshoot sign-in problems with Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/troubleshoot-conditional-access) 8. [deviceDetail resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/devicedetail) 9. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 10. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/AADNonInteractiveUserSignInLogs) ## Related codes [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS53001](https://brambrinkmeier.com/entra/aadsts/53001/), [AADSTS50097](https://brambrinkmeier.com/entra/aadsts/50097/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS530002](https://brambrinkmeier.com/entra/aadsts/530002/), [AADSTS530004](https://brambrinkmeier.com/entra/aadsts/530004/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS530003: Your device is required to be managed (fix)", https://brambrinkmeier.com/entra/aadsts/530003/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/530004/ # AADSTS530004: AcceptCompliantDevice setting isn't configured (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/530004/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/530004.json **Short answer:** AADSTS530004 means a guest user hit a device-based Conditional Access policy in the resource tenant, and that tenant doesn't trust device claims from the guest's home tenant. Microsoft's error reference doesn't list it, but a Microsoft troubleshooting article does. It is a B2B configuration gap with low attack value. The fix is the inbound trust settings in cross-tenant access. **Fix:** Resource tenant admin: in Cross-tenant access settings, open inbound trust for the guest's home tenant (or the defaults) and select Trust compliant devices or Trust Microsoft Entra hybrid joined devices. Exclude guests from Require approved client app. Guest: use your work device, not InPrivate. | Field | Value | |---|---| | Code | AADSTS530004 | | Category | Guests and tenants | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS530004 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS530004 (checked 30 October 2026). Microsoft documents it in a troubleshooting article, which quotes the message as: > AADSTS530004: AcceptCompliantDevice setting isn't configured for this organization. The administrator needs to configure this setting to allow external user access to protected resources. The article says it happens *"when a guest user tries to access an application or resource in a resource tenant"*, and that *"when an administrator reviews the sign-in logs in the home tenant, the same error code is displayed."* It names three scenarios, all with a Conditional Access policy in the resource tenant that applies to guests: | Policy control in the resource tenant | What Microsoft says to do | |---|---| | **Require device to be marked as compliant** | Configure cross-tenant access with **Trust compliant devices**, and make sure the guest's device is authenticated, enrolled in Intune or a supported MDM in the home tenant, and compliant. | | **Require Microsoft Entra hybrid joined device** | Configure cross-tenant access with **Trust Microsoft Entra hybrid joined devices**, and make sure the device is authenticated and hybrid joined in the home tenant. | | **Require approved client app** | *"This scenario isn't supported. To resolve the error, don't apply this control to guest users."* | The background is in Microsoft's cross-tenant access overview: by default, *"MFA and device claims from other Microsoft Entra organizations aren't trusted."* Without the trust setting, a guest's compliant or hybrid joined device counts for nothing in your tenant. ## Is it an attack? No. It is a mismatch between a device policy and the B2B trust settings. A guest who can't pass it is either on a device the home tenant doesn't manage or in a tenant you haven't chosen to trust. | Pattern | Likely meaning | |---|---| | 530004 for every guest from one partner | Your tenant has no trust setting for that partner, or the partner doesn't manage its devices. | | 530004 for one guest while colleagues from the same partner succeed | That guest's device isn't compliant or registered, or the browser can't send the device claim. | | 530004 starting on the day a device policy was extended to guests | The policy change, not the guests. Likely, but unconfirmed. | | 530004 on an approved-client-app policy | Unsupported for guests, per Microsoft. Exclude guests from that control. | ## How do I find it in my logs (KQL)? Microsoft says the error shows up in the home tenant's sign-in logs, and the article's verification steps use the resource tenant's sign-in logs. It doesn't say which table. Check where it lands: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "530004" | summarize Rows = count() by SourceTable ``` Which partner tenants and devices are affected. In the resource tenant, `HomeTenantId` tells you which partner the guest comes from. In the home tenant, `ResourceTenantId` tells you which external tenant your user was trying to reach. `DeviceDetail` property names come from the Graph `deviceDetail` resource; Microsoft's article says the **Join type** field shows which device claim was passed: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "530004" | extend TrustType = tostring(DeviceDetail.trustType), IsCompliant = tostring(DeviceDetail.isCompliant), Browser = tostring(DeviceDetail.browser) | summarize Rows = count(), Users = dcount(UserPrincipalName), Apps = make_set(AppDisplayName, 10) by HomeTenantId, ResourceTenantId, CrossTenantAccessType, UserType, TrustType, IsCompliant, Browser | sort by Rows desc ``` Our reading: an empty `TrustType` means no device claim reached the resource tenant, which points at the "device authentication fails" cases listed below rather than at the trust setting. Compare with a successful guest sign-in from the same partner. ## How does Conditional Access affect it? - 530004 only appears because a device control in **your** policy applies to guests. Microsoft lists the controls: compliant device, hybrid joined device and approved client app. - The approved client app control can't be satisfied by guests at all. Microsoft: *"This scenario isn't supported."* - If you don't want to trust a partner's devices, the alternative is to exclude guests from the device policy and cover them with an MFA policy instead. Our suggestion; weigh it against your own risk. ## How do I fix AADSTS530004? **For the guest user:** sign in from your work device in a normal browser window, not InPrivate or Incognito. If you still get the error, tell your contact in the organization you're visiting. Their admin has to change a setting. Your own IT may need to check that your device is compliant. **For admins of the resource tenant (where the app lives):** 1. Go to **Entra ID** > **External Identities** > **Cross-tenant access settings**. Edit the **Default settings** inbound defaults, or under **Organizational settings** add the guest's home tenant and open its inbound access. 2. On the **Trust settings** tab (for an organization, choose **Customize settings** first), select **Trust compliant devices**, **Trust Microsoft Entra hybrid joined devices**, or both, to match your policy. Select **Save**. 3. If the failing policy uses **Require approved client app**, exclude guests from it. Microsoft's troubleshooting article says to create the cross-tenant policy *"in the user's home tenant"*. The cross-tenant documentation describes trust settings as inbound settings that let *your* Conditional Access policies trust claims from an external organization. Our reading: the setting lives in the resource tenant, as a per-organization entry **for** the guest's home tenant. If you are the home tenant's admin, ask the resource tenant to configure it. **For admins of the guest's home tenant:** make sure the device is actually compliant or hybrid joined in your tenant. Microsoft lists these causes of failed device authentication: - *"When accessing using a browser in InPrivate or Incognito mode."* - *"When using unsupported browsers or devices, particularly on mobiles."* - *"When browser cookies are disabled."* - *"When a desktop or native application doesn't support device authentication or doesn't use Microsoft Authentication Broker."* ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Error AADSTS530004 - AcceptCompliantDevice setting isn't configured for this organization](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts530004-acceptcompliantdevice-setting-not-configured) 3. [Overview: Cross-tenant access with Microsoft Entra External ID](https://learn.microsoft.com/en-us/entra/external-id/cross-tenant-access-overview) 4. [Configure cross-tenant access settings for B2B collaboration](https://learn.microsoft.com/entra/external-id/cross-tenant-access-settings-b2b-collaboration) 5. [Conditional Access: Grant](https://learn.microsoft.com/en-gb/entra/identity/conditional-access/concept-conditional-access-grant) 6. [deviceDetail resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/devicedetail) 7. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS53001](https://brambrinkmeier.com/entra/aadsts/53001/), [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS530002](https://brambrinkmeier.com/entra/aadsts/530002/), [AADSTS530003](https://brambrinkmeier.com/entra/aadsts/530003/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS530004: AcceptCompliantDevice setting isn't configured (fix)", https://brambrinkmeier.com/entra/aadsts/530004/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/530031/ # AADSTS530031: Access policy does not allow token issuance (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/530031/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/530031.json **Short answer:** AADSTS530031 means a policy in the tenant refused to issue the token. Microsoft's error reference doesn't list it and we found no Microsoft page that does; the wording comes from user reports. Users see it where Conditional Access blocks a sign-in, and the same phrase appears in some 53003 messages. Treat it like 53003: find the policy in the sign-in log. **Fix:** Admin: open the 530031 row in the sign-in logs, read the Conditional Access tab, and adjust the policy if the block isn't intended. If no policy failed, check the user's Identity Protection risk. Developer: replace grant_type=password with an interactive MSAL flow. User: send IT the correlation ID. | Field | Value | |---|---| | Code | AADSTS530031 | | Category | Conditional Access | | Type | Failure | | Attack signal | Medium: worth a look in context | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS530031 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS530031 (checked 30 October 2026). We found no other Microsoft page that documents it either. The wording below comes from user reports. On Microsoft Q&A, a user posted this sign-in log entry: > Sign-in error code: 530031 > Failure reason: Access policy does not allow token issuance. The client app was **Browser**. The user said the account was still blocked after being excluded from every Conditional Access policy. The thread's title blames Identity Protection, but nobody in the thread confirmed that. A moderator (not identified as a Microsoft employee) answered that a matching Conditional Access policy was blocking token issuance. On a Tencent Cloud developer Q&A, a .NET app that requested a SharePoint token with `grant_type=password` got: > AADSTS530031: Access policy does not allow token issuance. The same response carried `error: interaction_required` and `suberror: message_only`. The accepted answer there also points at a Conditional Access policy for SharePoint. The phrase is not unique to 530031. Users quote it as the second sentence of the listed code [53003](https://brambrinkmeier.com/entra/aadsts/53003/): *"AADSTS53003: Access has been blocked by Conditional Access policies. The access policy does not allow token issuance."* Our reading: 530031 is a policy block in the same family as 53003. Microsoft doesn't document which kind of policy produces 530031 instead of 53003, so we can't say whether it is Conditional Access, Identity Protection, or something else. Don't build detections on that distinction until Microsoft documents it. ## Is it an attack? Usually not. It is a policy blocking a sign-in, like 53003. The attack value comes from the context. | Pattern | Likely meaning | |---|---| | 530031 for a user or app that worked before | A new or changed policy now applies to it. Users report exactly this. | | 530031 on a script using `grant_type=password` (ROPC) | The script can't satisfy the policy's requirements, since ROPC can't do interactive steps. Likely, going by the Tencent report. | | 530031 for a user excluded from all Conditional Access policies | A different policy layer may be involved. The Q&A user suspected Identity Protection; unconfirmed. | | 530031 from an unfamiliar IP or country | Our reasoning: the request got as far as a policy decision. Check the user's other sign-ins from that IP. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 530031 is logged in. The Q&A user saw it with client app **Browser**, which suggests interactive sign-ins, but check: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "530031" | summarize Rows = count() by SourceTable ``` The context of each block, side by side with 53003. `ConditionalAccessStatus` is documented as *"success, failure, or notApplied."* The risk columns help test the Identity Protection theory: ```kusto union (SigninLogs | project TimeGenerated, ResultType, ResultDescription, UserPrincipalName, AppDisplayName, ClientAppUsed, IPAddress, ConditionalAccessStatus, RiskLevelDuringSignIn, RiskState), (AADNonInteractiveUserSignInLogs | project TimeGenerated, ResultType, ResultDescription, UserPrincipalName, AppDisplayName, ClientAppUsed, IPAddress, ConditionalAccessStatus, RiskLevelDuringSignIn, RiskState) | where TimeGenerated > ago(30d) | where ResultType in ("530031", "53003") | summarize Rows = count(), Users = dcount(UserPrincipalName) by ResultType, ConditionalAccessStatus, RiskLevelDuringSignIn, RiskState, ClientAppUsed | sort by ResultType asc, Rows desc ``` If 530031 rows show `ConditionalAccessStatus == "notApplied"` while 53003 rows show `failure`, that supports a non-Conditional Access cause in your tenant. That is a test you can run, not a documented fact. ## How does Conditional Access affect it? - Both user reports and their answers point at a Conditional Access policy. Microsoft's Conditional Access troubleshooting page is the right tool even though it doesn't list 530031. - Microsoft's steps: open the sign-in, select the **Conditional Access** tab, which *"shows the specific policy or policies that resulted in the sign-in interruption."* The **Troubleshooting and support** tab may give the reason. - If the Conditional Access tab shows nothing that failed, use the sign-in diagnostic (**Basic info** > **Troubleshoot Event**) or the What If tool. ## How do I fix AADSTS530031? **For the user:** you can't fix this yourself. Send IT the error code, the time, and the correlation ID from the error page. **For developers:** stop using `grant_type=password` for user tokens. Our reading: ROPC has no way to show an MFA prompt or prove a device, so a policy that needs either blocks it. Use an interactive flow through MSAL, or a service principal for unattended jobs. **For admins:** 1. In **Entra ID** > **Monitoring & health** > **Sign-in logs**, filter on the user and the time and open the 530031 row. Read the **Conditional Access** tab first. 2. If a policy failed, decide whether the block is intended. Adjust the policy or the user's device, location or authentication method. 3. If no policy failed, check the user's risk state in Identity Protection and the second query above. Then run the sign-in diagnostic. 4. If you can't find the cause, open a support case. Microsoft asks for the request ID, date and time from the sign-in event. With no Microsoft documentation for this code, support is the only authoritative answer. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Identity Protection Blocks User: Error Code: 530031 (Microsoft Q&A 897426)](https://learn.microsoft.com/en-us/answers/questions/897426/identity-protection-blocks-user-error-code-530031) 3. [AADSTS530031 when requesting a token (Tencent Cloud developer Q&A)](https://cloud.tencent.com/developer/ask/sof/106773446) 4. [Token generation issue for newly registered app (Microsoft Q&A 1529778)](https://learn.microsoft.com/en-us/answers/questions/1529778/token-generation-issue-for-newly-registered-app-in) 5. [Troubleshoot sign-in problems with Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/troubleshoot-conditional-access) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 7. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/AADNonInteractiveUserSignInLogs) ## Related codes [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS530032](https://brambrinkmeier.com/entra/aadsts/530032/), [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS53001](https://brambrinkmeier.com/entra/aadsts/53001/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS530031: Access policy does not allow token issuance (fix)", https://brambrinkmeier.com/entra/aadsts/530031/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/530032/ # AADSTS530032: Blocked by a tenant security policy Canonical: https://brambrinkmeier.com/entra/aadsts/530032/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/530032.json **Short answer:** AADSTS530032 means a security policy set at the tenant level blocked the request, rather than a named Conditional Access policy. Microsoft's spray playbook lists it among events to review. Its sibling 530035 is the security defaults block, which legacy-auth sprays hit in tenants that use security defaults. **Fix:** Admin: review the tenant-level security settings to find which one matched the request. For the sibling 530035 (security defaults), move users off legacy authentication rather than turning security defaults off. User: use a browser or current Outlook or Teams, not an old mail client. | Field | Value | |---|---| | Code | AADSTS530032 | | Microsoft name | BlockedByConditionalAccessOnSecurityPolicy | | Category | Conditional Access | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts, [T1110.003](https://attack.mitre.org/techniques/T1110/003/) Brute Force: Password Spraying | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-11 | ## What does AADSTS530032 mean? Microsoft's description: > **BlockedByConditionalAccessOnSecurityPolicy**: The tenant admin has configured a security policy that blocks this request. Check the security policies that are defined on the tenant level to determine if your request meets the policy requirements. Microsoft's description does not say which tenant-level policy this refers to. It only separates it from a named Conditional Access policy, which returns 53003. Its sibling is **530035**: > **BlockedBySecurityDefaults**: Access has been blocked by security defaults. This is due to the request using legacy auth or being deemed unsafe by security defaults policies. If your tenant uses security defaults instead of Conditional Access, 530035 is the code to hunt as well. ## Is it an attack? Microsoft's password spray playbook lists *"530032 - Blocked by Conditional Access on Security Policy"* among the sign-in events to review in a spray investigation. The block itself is a control working. What matters is who triggered it and from where. | Pattern | Likely meaning | |---|---| | One user, known device and location, right after a tenant security setting changed | The new setting catching a real user. Configuration, not attack. | | Many different users from one IP or range | In practice, an automated attempt your tenant-level policy is stopping. Check the same IP for 50126 and 50053. | | **530035** on legacy clients (`ClientAppUsed` IMAP, POP, SMTP, Exchange ActiveSync) | Security defaults blocking legacy auth, as Microsoft's description says. Across many users from one IP, this is usually a legacy-auth spray. | | 530032 or 530035 from an IP that also got a success for any user | Something got through by another path. Investigate that success first. | This page does not claim whether the first factor had succeeded on a 530032 row. Microsoft's description doesn't say, and the answer may depend on the policy. Check `ConditionalAccessStatus` and `AuthenticationRequirement` on your own rows before drawing that conclusion. ## How do I find it in my logs (KQL)? Both codes, grouped by source, with the clients used: ```kusto SigninLogs | where TimeGenerated > ago(7d) | where ResultType in ("530032", "530035") | summarize Attempts = count(), Users = dcount(UserPrincipalName), Clients = make_set(ClientAppUsed, 10), Apps = make_set(AppDisplayName, 10), Reasons = make_set(ResultDescription, 5) by IPAddress, ResultType | sort by Users desc ``` Did any IP that hit these blocks also get further somewhere else? ```kusto let blockedIPs = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType in ("530032", "530035") | distinct IPAddress; SigninLogs | where TimeGenerated > ago(1d) | where IPAddress in (blockedIPs) | where ResultType in ("0", "50076", "50074", "50079", "53003", "50055") | project TimeGenerated, UserPrincipalName, IPAddress, ResultType, ResultDescription, ConditionalAccessStatus, AppDisplayName, ClientAppUsed | sort by TimeGenerated asc ``` `ResultType` is a string column, so compare with `"530032"`. Legacy clients that replay a stored password can show up in `AADNonInteractiveUserSignInLogs`, which is why the second query reads both tables. ## How do Conditional Access and MFA affect it? - 530032 is not a named Conditional Access policy result. If you search the **Conditional Access** tab for the policy, you may not find one. Microsoft points you at the tenant-level security policies instead. - 530035 comes from security defaults, not from a Conditional Access policy. If you later replace security defaults with your own Conditional Access policies, make sure one of them blocks legacy authentication too. - Neither code proves MFA is working for the accounts involved. They show that one specific request was refused. ## How do I fix AADSTS530032? **For the user:** use a modern app (a browser, current Outlook or Teams) instead of an old mail client. If the block continues, give your admin the time and the correlation ID from the error page. **For admins:** 1. For 530032, review the tenant-level security settings Microsoft's description refers to, and find which one matched this request. 2. For 530035, find the client in `ClientAppUsed`. Move real users and devices off legacy authentication rather than turning security defaults off. 3. If the first query shows many users from one IP, treat it as a spray. Use the second query to find any account that got past the password, then reset and revoke sessions for it. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Password spray investigation (Microsoft incident response playbook)](https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray) 3. [Troubleshoot sign-in problems with Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/troubleshoot-conditional-access) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS50053](https://brambrinkmeier.com/entra/aadsts/50053/), [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS50076](https://brambrinkmeier.com/entra/aadsts/50076/), [AADSTS530031](https://brambrinkmeier.com/entra/aadsts/530031/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS530032: Blocked by a tenant security policy", https://brambrinkmeier.com/entra/aadsts/530032/ (CC BY 4.0), last updated 2026-10-11. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/650052/ # AADSTS650052 fix: app needs a service your tenant lacks Canonical: https://brambrinkmeier.com/entra/aadsts/650052/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/650052.json **Short answer:** AADSTS650052 means an app asked for access to an API (a service) that has no service principal in your tenant, so consent or sign-in can't go ahead. It is a configuration gap with low attack value. Users report it most with the Microsoft Advertising API. An admin fixes it by granting admin consent, which Microsoft says adds the missing app to the tenant. **Fix:** Admin: create the missing service principal from the app ID in the error (`New-MgServicePrincipal -AppId `) or grant admin consent, after checking what the app asks for. User: send IT the service name and ID from the error. Developer: check which APIs your app requests. | Field | Value | |---|---| | Code | AADSTS650052 | | Category | Consent and app permissions | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS650052 mean? Microsoft's description: > The app needs access to a service `("{name}")` that your organization `"{organization}"` hasn't subscribed to or enabled. Contact your IT Admin to review the configuration of your service subscriptions. Microsoft gives this code no name. The "service" is an API the app wants permissions on: the **resource**. Microsoft's consent troubleshooting article says it plainly: *"This error means the resource doesn't exist in your organization."* "Doesn't exist" means the resource has no **service principal** in your tenant. Microsoft explains that *"A service principal must be created in each tenant where the application is used"*. An API owned by Microsoft or by another company only becomes usable in your tenant once that object exists. Users often see a different wording. In a Microsoft Q&A thread the message read *"The app is trying to access a service '{guid}…'(Microsoft Advertising API Service) that your organization 'xxxxx' lacks a service principal for."* That version names the service's app ID, which is what an admin needs. **How it differs from [500011](https://brambrinkmeier.com/entra/aadsts/500011/):** both mean the resource has no service principal in the tenant, and Microsoft's consent article puts them under the same troubleshooting step. Our reading: 650052 tends to show up while the app asks for consent, and 500011 when it asks for a token. The root cause can be the same, but Microsoft's consent article gives different first steps: admin consent for 650052, and checking the resource identifier and tenant with the app owner for 500011. If the missing object is the **client** app rather than the API, see [700016](https://brambrinkmeier.com/entra/aadsts/700016/). ## Is it an attack? Not by itself. Nothing is granted. The request stops because the API has no object in your tenant to grant anything on. | Pattern | Likely meaning | |---|---| | 650052 when connecting a tool to Microsoft Advertising | The most common report. The Microsoft Advertising API Service has no service principal in the tenant. Users also report it in third-party connectors such as Fivetran. | | 650052 for an app built in-house or with Terraform | The app asks for a scope on a custom API that only exists in the developer's tenant. Users report this; the HashiCorp thread has no confirmed cause. | | 650052 for many users of one app, all at first sign-in | No admin has set the app up yet. Every user hits the same gap. | | 650052 for an unknown app asking for unusual APIs | Worth a look before you fix anything. Our interpretation: an admin who "fixes" the error by granting consent also grants whatever else the app asks for. | The risk is in the fix, not in the error. Microsoft warns that granting admin consent *"is a sensitive operation, potentially allowing the application's publisher access to significant portions of your organization's data"*. Check what the app requests before you consent on everyone's behalf. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 650052 lands in. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "650052" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Which client apps hit it, for how many users, and the error text (which should name the missing service): ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "650052" | summarize Rows = count(), Users = dcount(UserPrincipalName), Resources = make_set(ResourceDisplayName, 5), Messages = make_set(ResultDescription, 3), FirstSeen = min(TimeGenerated) by AppId, AppDisplayName | sort by Users desc ``` Whether `ResourceDisplayName` is filled for a resource that has no service principal isn't documented. If it is empty, read the service name and ID from `ResultDescription` or from the message the user saw. `ResultType` is a **string** column, so compare it with `"650052"`. ## How do I fix AADSTS650052? **For the user:** you can't fix this yourself. Send your IT team the app name, and the service name and ID from the error message. **For developers:** check which APIs your app's registration requests. If you request a scope on your own API, that API needs a service principal in the customer's tenant too, created by consent or by their admin. Tell customers which app IDs they need. Ask only for the APIs you actually call. **For admins:** 1. Read the service's app ID from the error. Check under **Enterprise applications** that it really is missing. 2. Decide whether you want the app to have this access. Review the permissions the app requests. 3. Create the missing service principal. Microsoft's steps (Cloud Application Administrator or Application Administrator): ```powershell Connect-MgGraph -Scopes "Application.ReadWrite.All" New-MgServicePrincipal -AppId ``` The Azure CLI equivalent is `az ad sp create --id `. 4. Or grant admin consent. Microsoft's consent article gives an admin consent URL for this error. Microsoft's article gives it as `https://login.microsoftonline.com//oauth2/authorize?response_type=code&client_id=&prompt=admin_consent`, where `client_id` is the resource the app is trying to reach, not your own app. Microsoft also says that *"Granting tenant-wide admin consent to the application adds it to your tenant."* 5. For Microsoft Advertising, an answer in the Microsoft Q&A thread suggests making sure at least one admin of your tenant is added to Microsoft Advertising and enabled for work accounts. One commenter suggests `New-MgServicePrincipal -AppId "{app-id}"`; nobody in the thread confirms either worked. Fivetran's knowledge base instead grants admin consent to the Microsoft Advertising app in the portal. Microsoft Learn doesn't document a fix for Microsoft Advertising specifically. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Troubleshoot consent issues in Microsoft Entra ID](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/troubleshoot-consent-issues) 3. [Application and service principal objects in Microsoft Entra ID](https://learn.microsoft.com/entra/identity-platform/app-objects-and-service-principals) 4. [Create an enterprise application from a multitenant application](https://learn.microsoft.com/en-gb/entra/identity/enterprise-apps/create-service-principal-cross-tenant) 5. [Grant tenant-wide admin consent to an application](https://learn.microsoft.com/entra/identity/enterprise-apps/grant-admin-consent) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 7. [Microsoft Q&A: Microsoft OAuth Error Code AADSTS650052 (user reports)](https://learn.microsoft.com/en-us/answers/questions/1145813/microsoft-oauth-error-code-aadsts650052) 8. [Fivetran: AADSTS650052 Service Principal Missing (vendor KB)](https://fivetran.com/docs/connectors/applications/microsoft-advertising/troubleshooting/aadsts650052-service-principal-missing) 9. [HashiCorp Discuss: AADSTS650052 when creating azuread_application (user report)](https://discuss.hashicorp.com/t/error-aadsts650052-when-creating-azuread-application/53485) ## Related codes [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS500014](https://brambrinkmeier.com/entra/aadsts/500014/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS650052 fix: app needs a service your tenant lacks", https://brambrinkmeier.com/entra/aadsts/650052/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/650056/ # AADSTS650056: Misconfigured application (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/650056/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/650056.json **Short answer:** AADSTS650056 means Microsoft Entra ID refused a sign-in because the app is misconfigured: it doesn't list the permissions it asks for, an admin hasn't consented, or (for SAML) the issuer in the request doesn't match the app's identifier. It is a configuration error with low attack value. Fix the app's API permissions or SAML identifier, then grant consent. **Fix:** SAML app admin: make the Identifier (Entity ID) in the enterprise app match the Issuer the app sends. OAuth app developer: list every requested permission under API permissions, then have an admin grant consent after checking the publisher. User: send IT the app name and Client app ID. | Field | Value | |---|---| | Code | AADSTS650056 | | Category | Consent and app permissions | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS650056 mean? Microsoft's description: > Misconfigured application. This could be due to one of the following: the client has not listed any permissions for '{name}' in the requested permissions in the client's application registration. Or, the admin has not consented in the tenant. Or, check the application identifier in the request to ensure it matches the configured client application identifier. Or, check the certificate in the request to ensure it's valid. Please contact your admin to fix the configuration or consent on behalf of the tenant. Client app ID: {ID}. Please contact your admin to fix the configuration or consent on behalf of the tenant. The reference table gives this code no PascalCase name. Microsoft's troubleshooting article for 650056 lists three causes: - *"The Issuer provided in the SAMLRequest is not valid."* - *"The application doesn't have the required permissions to call Microsoft Graph APIs."* - *"The admin hasn't consented to the permissions for the application on behalf of the tenant."* The description also mentions a fourth check, the certificate in the request. The troubleshooting article doesn't expand on it. So there are two quite different families behind one code. In SAML sign-ins it is usually an identifier mismatch. In OAuth and OpenID Connect sign-ins it is usually permissions or consent. ### How it differs from neighbouring consent codes - **[65001](https://brambrinkmeier.com/entra/aadsts/65001/)**: the permissions are configured, but nobody has consented to them yet. The fix is an interactive consent. - **[90094](https://brambrinkmeier.com/entra/aadsts/90094/)**: the user is allowed to see the consent prompt but the permissions need an admin. - **650056**: our reading is that the problem sits one step earlier. The app asked for something its own registration doesn't list, or the request doesn't match the app it claims to be. Consent alone may not fix it. ## Is it an attack? Almost never. 650056 comes from how an app is registered or configured, and the sign-in fails before any data is released. | Pattern | Likely meaning | |---|---| | 650056 for every user of a new SAML app | The **Identifier (Entity ID)** in the enterprise app doesn't match the Issuer the SaaS app sends. A setup mistake. | | 650056 for every user of an app after a vendor update | The vendor changed the Issuer or started asking for a permission the registration doesn't list. | | 650056 for one app you own, after someone edited its API permissions | A permission was removed, or added without admin consent. | | 650056 for an app nobody in your organisation recognises | Our interpretation: a user tried an unfamiliar app. The app got nothing, but find out what it is before anyone grants it consent. | The last row is where the security work sits. 650056 often ends with the message *"contact your admin to fix the configuration or consent on behalf of the tenant"*, so users forward it to IT. Microsoft warns that *"Granting admin consent on behalf of an organization is a sensitive operation, potentially allowing the application's publisher access to significant portions of your organization's data."* Check who publishes the app and what it asks for before you consent. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 650056 lands in. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "650056" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which apps fail, for how many users, and over which protocol. `AuthenticationProtocol` helps you pick the right fix, SAML or OAuth: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "650056" | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Protocols = make_set(AuthenticationProtocol, 5), Resources = make_set(ResourceDisplayName, 5) by AppId, AppDisplayName | sort by Users desc ``` Microsoft's consent troubleshooting article points to the audit log for failed consent: category **ApplicationManagement**, status **Failure**, activity **Consent to application**. The same filter in KQL, to see if someone tried to consent and it failed: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where Category == "ApplicationManagement" | where OperationName == "Consent to application" | where Result =~ "failure" | project TimeGenerated, App = tostring(TargetResources[0].displayName), ByUser = tostring(InitiatedBy.user.userPrincipalName), ResultReason | sort by TimeGenerated desc ``` Whether `AuthenticationProtocol` is filled in on a 650056 failure isn't documented; if it is empty, use `ResourceDisplayName` and the app's own configuration to tell SAML from OAuth. `ResultType` is a **string** column, so compare it with `"650056"`. ## How do I fix AADSTS650056? **For the user:** you can't fix this yourself. Send your IT team the app name and the **Client app ID** from the error message. **For developers (you own the app registration):** 1. In **App registrations** > your app > **API permissions**, check that every permission your code requests is listed. Microsoft's article says to confirm the app has at least the **User.Read** delegated permission from **Microsoft Graph**. 2. Check the **Status** column. Microsoft's article says that if a permission isn't consented to, the value is **Pending** or blank. If it is consented to, the value is *"Granted for [Tenant Name]."* 3. Compare the scopes in the sign-in request with what is listed. Microsoft's consent troubleshooting article shows the scope part of the request as an example: `Openid+User.Read+Directory.Read.All`. 4. Check that the application identifier in the request matches the registration, as the description asks. In Microsoft's consent URL examples, an app that accesses itself as the resource uses the same value for app ID and App ID URI. **For admins:** 1. **SAML app:** the Issuer in the SAML request must match the **Identifier (Entity ID)** in the enterprise app. Microsoft gives two fixes: update the Identifier in Entra to match the Issuer, or have the vendor send the correct Issuer. 2. **App your organisation doesn't own:** sign in to the app with an admin account and select **Consent on behalf of your organization** on the consent screen. If no consent screen appears, Microsoft says to delete the app from **Enterprise applications** and sign in again. 3. **Consent button not available:** Microsoft's article shows how to build a consent URL with `prompt=consent` on the v1 or v2.0 authorize endpoint. For tenant-wide admin consent, Microsoft's admin consent article gives the format `https://login.microsoftonline.com/{organization}/adminconsent?client_id={client-id}`. 4. Granting tenant-wide consent needs Privileged Role Administrator for any permission, or Cloud Application Administrator, AI Administrator or Application Administrator for anything except Microsoft Graph app roles (application permissions). 5. Before you consent, check the publisher and the permissions. Microsoft: *"Permissions granted programmatically aren't subject to review or confirmation. They take effect immediately."* ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Error AADSTS650056 - Misconfigured application](https://learn.microsoft.com/en-us/troubleshoot/azure/active-directory/error-code-aadsts650056-misconfigured-app) 3. [Troubleshoot consent issues in Microsoft Entra ID](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/troubleshoot-consent-issues) 4. [Grant tenant-wide admin consent to an application](https://learn.microsoft.com/entra/identity/enterprise-apps/grant-admin-consent) 5. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) ## Related codes [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS90094](https://brambrinkmeier.com/entra/aadsts/90094/), [AADSTS90095](https://brambrinkmeier.com/entra/aadsts/90095/), [AADSTS65004](https://brambrinkmeier.com/entra/aadsts/65004/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS65005](https://brambrinkmeier.com/entra/aadsts/65005/), [AADSTS76021](https://brambrinkmeier.com/entra/aadsts/76021/), [AADSTS500031](https://brambrinkmeier.com/entra/aadsts/500031/), [AADSTS650052](https://brambrinkmeier.com/entra/aadsts/650052/), [AADSTS1003031](https://brambrinkmeier.com/entra/aadsts/1003031/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS650056: Misconfigured application (fix)", https://brambrinkmeier.com/entra/aadsts/650056/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/700003/ # AADSTS700003: Device object was not found in the tenant (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/700003/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700003.json **Short answer:** AADSTS700003 means the device used for the sign-in no longer exists in the user's home tenant, usually because an admin or a cleanup job deleted it. Microsoft's error reference doesn't list it, but a Microsoft troubleshooting article does. Low attack value. The fix is to re-register or re-join the device; the audit log shows who deleted it. **Fix:** Admin: find the Delete device event in the audit log. If the device should stay, have the user re-register or re-join it (Entra joined: dsregcmd /forcerecovery; hybrid joined: dsregcmd /leave, then reboot). Integration owner: re-authorize the connection. User: tell IT. | Field | Value | |---|---| | Code | AADSTS700003 | | Category | Devices | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS700003 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700003 (checked 30 October 2026). Microsoft documents it in a troubleshooting article. When you sign in to an app integrated with Microsoft Entra ID, you get AADSTS700003 with one of these messages: > Device object was not found in the tenant '\' directory. > Your organization has deleted this device. Microsoft's cause: *"This issue occurs because the device object is deleted on your home tenant. When a device is deleted, the "Delete device" activity type is recorded in the Microsoft Entra audit log."* The article covers all three ways a device gets an identity: Microsoft Entra registered, Microsoft Entra joined and Microsoft Entra hybrid joined. Our reading: the device still holds credentials tied to its old device object, such as its Primary Refresh Token, and tries to use them. Entra can't find the object, so it refuses. This is the deleted-device counterpart of [135011](https://brambrinkmeier.com/entra/aadsts/135011/), where the device object still exists but is disabled. Users report it in places that aren't obviously device-bound. An Atlassian knowledge base article describes a Jira Data Center mailbox connected through OAuth 2.0 that stopped sending and receiving mail, with this in the log: > AADSTS700003: Device object was not found in the tenant 'xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx' directory. Atlassian's fix was to regenerate the OAuth credentials and tokens and apply them in Jira again. Atlassian attributes the cause to a Microsoft security fix; Microsoft's article doesn't mention one. On Microsoft Q&A, a user hit "Error code 700003" in Microsoft Teams on a family computer that, they said, the school district's IT had removed. ## Is it an attack? Usually not. It follows a device deletion, which is normal cleanup. | Pattern | Likely meaning | |---|---| | 700003 for several users the day after a stale-device cleanup | The cleanup removed devices that were still in use. Check the audit log for who ran it. | | 700003 for one user after a reinstall or device swap | The old device object was deleted while something still used it. Re-register the device. | | 700003 from a server-side integration | A token tied to a device was stored by a service. Atlassian's fix: create new tokens. | | 700003 after you deleted a device during incident response | Probably the device you removed, still trying to sign in. Its IP in the sign-in rows shows where it is. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 700003 is logged in. Check where it lands first: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "700003" | summarize Rows = count() by SourceTable ``` Who is affected and from where. `DeviceDetail` is dynamic in `SigninLogs` and a string in `AADNonInteractiveUserSignInLogs`, so each leg parses it first. Property names come from the Graph `deviceDetail` resource; we don't know whether they are filled in for a device that no longer exists: ```kusto let rows = union (SigninLogs | extend D = parse_json(tostring(DeviceDetail)) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, IPAddress, UserAgent, D), (AADNonInteractiveUserSignInLogs | extend D = parse_json(DeviceDetail) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, IPAddress, UserAgent, D); rows | where TimeGenerated > ago(14d) | where ResultType == "700003" | extend DeviceId = tostring(D.deviceId), DeviceName = tostring(D.displayName), OS = tostring(D.operatingSystem) | summarize Rows = count(), Apps = make_set(AppDisplayName, 10), IPs = make_set(IPAddress, 10), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by UserPrincipalName, DeviceId, DeviceName, OS | sort by FirstSeen asc ``` Who deleted devices, and when. Microsoft's article names the audit activity **Delete device**. `TargetResources` and `InitiatedBy` are dynamic columns; the property paths below follow their usual shape, so check them against one row of your own before you rely on them: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where OperationName == "Delete device" | extend DeviceName = tostring(TargetResources[0].displayName), DeviceObjectId = tostring(TargetResources[0].id), ByUser = tostring(InitiatedBy.user.userPrincipalName), ByApp = tostring(InitiatedBy.app.displayName) | project TimeGenerated, DeviceName, DeviceObjectId, ByUser, ByApp, Result, LoggedByService | sort by TimeGenerated desc ``` Line up the `FirstSeen` time from the second query with the deletions in the third. A deletion shortly before the first 700003 for that user is your cause. ## How do I fix AADSTS700003? **For the user:** tell IT. Microsoft's article says to *"engage the home tenant administrators to determine when and why your device object is deleted."* If IT agrees the device should stay, re-register it with the steps below. On a school or work device you don't manage, don't do this on your own. **For admins:** find the deletion with the third query. Then, if the device should stay, have the user re-register or re-join it. Microsoft's steps by join type: | Join type | Microsoft's steps | |---|---| | Microsoft Entra registered, Windows 10/11 | **Settings** > **Accounts** > **Access Work or School**, select the account, **Disconnect**, then register the device again. | | Microsoft Entra registered, iOS and Android | In Microsoft Authenticator, **Settings** > **Device Registration** > **Unregister device**, then register again. | | Microsoft Entra registered, macOS | Use Intune Company Portal to unenroll the device and remove the registration, then register again. | | Microsoft Entra joined | In an elevated PowerShell console, run the command below, select **Sign in** and sign in with the Entra ID account. | | Microsoft Entra hybrid joined | In an elevated PowerShell console, run the command below, reboot, and sign in with the domain credential. | Microsoft Entra joined: ```powershell dsregcmd /forcerecovery ``` Microsoft Entra hybrid joined: ```powershell dsregcmd /leave ``` For a hybrid joined device, our reading is that the device registers again through the normal hybrid join process after the reboot. Check that a new device object appears. **For developers and integration owners:** a stored token that fails with 700003 won't recover. Re-authorize the connection to get new tokens, as Atlassian recommends for Jira mailboxes. **To prevent it:** our suggestion is to check sign-in activity before a stale-device cleanup deletes a device, and to disable before you delete. A disabled device fails with [135011](https://brambrinkmeier.com/entra/aadsts/135011/) instead, which gives you a window to undo the change before the object is gone. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Error AADSTS700003 - Device object was not found in the tenant '' directory](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts700003-device-object-not-found) 3. [Failure to connect to Office365 mail box due to AADSTS700003 (Atlassian KB)](https://support.atlassian.com/jira/kb/failure-to-connect-to-office365-mail-box-due-to-aadsts700003-device-object-was-not-found-in-the-tenant/) 4. [Error code 700003 (Microsoft Q&A 2278445)](https://learn.microsoft.com/en-us/answers/questions/2278445/error-code-700003) 5. [deviceDetail resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/devicedetail) 6. [AuditLogs table reference (Azure Monitor)](https://learn.microsoft.com/azure/azure-monitor/reference/tables/auditlogs) 7. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS135011](https://brambrinkmeier.com/entra/aadsts/135011/), [AADSTS50097](https://brambrinkmeier.com/entra/aadsts/50097/), [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/), [AADSTS50173](https://brambrinkmeier.com/entra/aadsts/50173/), [AADSTS5000611](https://brambrinkmeier.com/entra/aadsts/5000611/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS700003: Device object was not found in the tenant (fix)", https://brambrinkmeier.com/entra/aadsts/700003/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/700016/ # AADSTS700016: Application not found in the directory Canonical: https://brambrinkmeier.com/entra/aadsts/700016/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700016.json **Short answer:** AADSTS700016 means the client application ID in the request isn't found in the tenant the request was sent to. It is almost always a developer error: wrong client ID, wrong tenant, or an app never added to the tenant. Unknown client IDs or a deleted malicious app still trying to sign in are worth a look. **Fix:** Developer: compare the client ID in your config with the app registration's Application (client) ID, and check that the authority URL names the tenant where the app is registered (or that a multi-tenant app is consented there). If the app was deleted, restore it or register a new one. | Field | Value | |---|---| | Code | AADSTS700016 | | Microsoft name | UnauthorizedClient_DoesNotMatchRequest | | Category | App configuration | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs`, `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-25) | | Last updated | 2026-10-30 | ## What does AADSTS700016 mean? Microsoft's description: > **UnauthorizedClient_DoesNotMatchRequest**: The application wasn't found in the directory/tenant. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have misconfigured the identifier value for the application or sent your authentication request to the wrong tenant. The application that is missing is the **client** (the app asking for a token). If the missing object is the API being called, the error is [500011](https://brambrinkmeier.com/entra/aadsts/500011/) instead. ## Reproduced in the lab On 25 October 2026 an automated lab run sent a token request with a client ID that isn't registered anywhere. Entra returned `AADSTS700016` with this first line: > AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. That confirms the code and its wording at the token endpoint. The same attempt in the lab tenant's sign-in log (Entra admin center, interactive user sign-ins), with identifiers left out: | Field | Value in the lab row | |---|---| | Status | Failure | | Sign-in error code | 700016 | | Failure reason | Application with identifier '{appIdentifier}' was not found in the directory '{tenantName}'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. | | Application | (empty) | | Application ID | the unknown client ID from the request | | App owner tenant ID | (empty) | | Resource | Microsoft Graph | | Conditional Access | Not Applied | | User type | Member | The **Application** name is empty and there is no app owner tenant, only the unknown client ID. In `SigninLogs` that should appear as an empty `AppDisplayName` with an `AppId` that matches nothing in your tenant, which is a clean way to find these rows. The KQL below was run on the lab rows ([how](https://brambrinkmeier.com/methodology/)). The first query found both lab rows, one per unknown client ID. The second query, with the placeholder replaced by one of those IDs, found its row. ## Is it an attack? Almost always not. Typical causes: - A typo or copy-paste error in the client ID. - The request goes to the wrong tenant (wrong tenant ID or domain in the authority URL). - A single-tenant app used from another tenant. - A multi-tenant app that nobody in your tenant has consented to yet. - An app registration that was deleted while a script or service still uses it. | Pattern | Likely meaning | |---|---| | One internal app ID, failing since a deployment | Wrong client ID or tenant in config. Benign. | | An app you deleted recently, still failing | Something still uses it. Find and update the caller. | | An app you **removed during an incident** (for example after an illicit consent grant), still failing | **The attacker's tooling is still trying.** Note the IPs and times. | | Client IDs you don't recognise, from external IPs, across your tenant | Someone checking whether their app exists in your tenant. Investigate. | The last two rows are **our reasoning**, not Microsoft statements. Microsoft's illicit-consent guidance describes removing a malicious app's access; it doesn't describe the 700016 rows that follow. If you remove the service principal, a client that still uses that app ID against your tenant would match the description above. Two neighbouring codes may show instead: **700011** (*"Application with identifier {appIdentifier} was not found in the directory"*) for a removed app, and **7000112** (*"The application is disabled"*) while the service principal is disabled. Which one a removed app returns isn't documented; the [consent phishing guide](https://brambrinkmeier.com/guides/investigate-consent-phishing-entra-id/) treats all three as the aftermath to watch for. ## How do I find it in my logs (KQL)? 700016 grouped by the client app ID, so you can check each one against your app registrations: ```kusto SigninLogs | where TimeGenerated > ago(14d) | where ResultType == "700016" | summarize Attempts = count(), Users = dcount(UserPrincipalName), IPs = make_set(IPAddress, 10), AppNames = make_set(AppDisplayName, 5), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppId | sort by Attempts desc ``` `AppDisplayName` may be empty on these rows, since the tenant has no object for the app. Look up the `AppId` yourself. After an incident: has a removed app ID tried again? ```kusto let removedApp = ""; union (SigninLogs | where AppId == removedApp), (AADServicePrincipalSignInLogs | where AppId == removedApp) | where TimeGenerated > ago(30d) | project TimeGenerated, Type, ResultType, ResultDescription, IPAddress, UserPrincipalName, ServicePrincipalName | sort by TimeGenerated desc ``` The empty `AppDisplayName` is confirmed in the lab's user sign-in rows. Whether 700016 also shows up in `AADServicePrincipalSignInLogs` is not verified. Microsoft's table reference for the service principal table describes `ResultType` as Success or Failure, so check whether the numeric code appears there before you build a rule on it. ## How does Conditional Access affect it? - 700016 is not a Conditional Access result. There is no application object in the tenant for a policy to target. - Once the app is added or consented, your policies apply as normal. Conditional Access targets the **resource** being requested, not the client application, so a policy on "All resources" or on the specific API covers the tokens this client asks for. - The control that matters here is consent. Microsoft's illicit-consent guidance notes that resetting passwords or requiring MFA isn't effective against an app that already holds consent. Removing the app's grants and service principal is what ends that access, and 700016 can be what the attacker's tool sees afterwards. ## How do I fix AADSTS700016? **For developers:** 1. Compare the client ID in your code or config with the **Application (client) ID** on the app registration. 2. Check the authority URL. The tenant in it must be the tenant where the app is registered, or the app must be multi-tenant and consented in the target tenant. 3. If the app was deleted, restore it or register a new one and update every caller. **For admins:** 1. Check each unknown `AppId` from the first query. If it is a third-party app nobody asked for, leave it out of the tenant. 2. If the app ID belongs to something you removed during an incident, keep the evidence (IPs, times, user agents) and don't re-add the app. ## Evidence Reproduced in a lab tenant on 2026-10-25 (ROPC token request against a lab tenant; scenario: Unknown client ID). First line returned: > AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. Sign-in log row read: 2026-10-30. KQL run against the exported lab rows: 2026-10-30. Lab-run rows naming this code (31; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Unknown client ID | 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Unknown client ID | 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Unknown client ID | 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Unknown client ID | 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Unknown client ID | 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Unknown client ID | 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-30 | Unknown client ID | 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-31 | Unknown client ID | 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-31 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-31 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Unknown client ID | 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-31 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-31 | Device code on /common by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | | 2026-10-31 | Device code on /organizations by a single-tenant app | 90133 / 700016 / 50194 | 50059 | AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Detect and remediate illicit consent grants](https://learn.microsoft.com/en-us/defender-office-365/detect-and-remediate-illicit-consent-grants) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 4. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS50001](https://brambrinkmeier.com/entra/aadsts/50001/), [AADSTS50059](https://brambrinkmeier.com/entra/aadsts/50059/), [AADSTS50105](https://brambrinkmeier.com/entra/aadsts/50105/), [AADSTS50194](https://brambrinkmeier.com/entra/aadsts/50194/), [AADSTS51004](https://brambrinkmeier.com/entra/aadsts/51004/), [AADSTS65002](https://brambrinkmeier.com/entra/aadsts/65002/), [AADSTS65005](https://brambrinkmeier.com/entra/aadsts/65005/), [AADSTS70002](https://brambrinkmeier.com/entra/aadsts/70002/), [AADSTS70021](https://brambrinkmeier.com/entra/aadsts/70021/), [AADSTS70025](https://brambrinkmeier.com/entra/aadsts/70025/), [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS90009](https://brambrinkmeier.com/entra/aadsts/90009/), [AADSTS90019](https://brambrinkmeier.com/entra/aadsts/90019/), [AADSTS90094](https://brambrinkmeier.com/entra/aadsts/90094/), [AADSTS90095](https://brambrinkmeier.com/entra/aadsts/90095/), [AADSTS90133](https://brambrinkmeier.com/entra/aadsts/90133/), [AADSTS500014](https://brambrinkmeier.com/entra/aadsts/500014/), [AADSTS500031](https://brambrinkmeier.com/entra/aadsts/500031/), [AADSTS500113](https://brambrinkmeier.com/entra/aadsts/500113/), [AADSTS500200](https://brambrinkmeier.com/entra/aadsts/500200/), [AADSTS501051](https://brambrinkmeier.com/entra/aadsts/501051/), [AADSTS650052](https://brambrinkmeier.com/entra/aadsts/650052/), [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/), [AADSTS700024](https://brambrinkmeier.com/entra/aadsts/700024/), [AADSTS700051](https://brambrinkmeier.com/entra/aadsts/700051/), [AADSTS700054](https://brambrinkmeier.com/entra/aadsts/700054/), [AADSTS900023](https://brambrinkmeier.com/entra/aadsts/900023/), [AADSTS900144](https://brambrinkmeier.com/entra/aadsts/900144/), [AADSTS900439](https://brambrinkmeier.com/entra/aadsts/900439/), [AADSTS1002016](https://brambrinkmeier.com/entra/aadsts/1002016/), [AADSTS1003031](https://brambrinkmeier.com/entra/aadsts/1003031/), [AADSTS5000225](https://brambrinkmeier.com/entra/aadsts/5000225/), [AADSTS5002730](https://brambrinkmeier.com/entra/aadsts/5002730/), [AADSTS7000014](https://brambrinkmeier.com/entra/aadsts/7000014/), [AADSTS7000110](https://brambrinkmeier.com/entra/aadsts/7000110/), [AADSTS7000112](https://brambrinkmeier.com/entra/aadsts/7000112/), [AADSTS7000216](https://brambrinkmeier.com/entra/aadsts/7000216/), [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS7000222](https://brambrinkmeier.com/entra/aadsts/7000222/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS9002326](https://brambrinkmeier.com/entra/aadsts/9002326/), [AADSTS9002331](https://brambrinkmeier.com/entra/aadsts/9002331/), [AADSTS9002346](https://brambrinkmeier.com/entra/aadsts/9002346/), [AADSTS9010010](https://brambrinkmeier.com/entra/aadsts/9010010/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS700016: Application not found in the directory", https://brambrinkmeier.com/entra/aadsts/700016/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/700024/ # AADSTS700024: Client assertion is not within its valid time range (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/700024/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700024.json **Short answer:** AADSTS700024 means an app signed in with a client assertion (a signed JWT, or a federated token from GitHub Actions or Azure DevOps) that was expired or not yet valid. Microsoft's error reference doesn't list it. The usual cause is a long CI/CD job that reuses its first token. Low attack value. Fetch a fresh token right before each use. **Fix:** Developer: get a fresh token right before each use. GitHub Actions: request Azure tokens early, or run `az login` again before late steps. Azure DevOps past about 1 hour: use workload identity federation with a managed identity. Self-signed JWT: build a new assertion for each request. | Field | Value | |---|---| | Code | AADSTS700024 | | Category | App configuration | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS700024 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700024 (checked 30 October 2026). The lab reproduced it. A client-credentials request used a GitHub Actions OIDC token as the client assertion (through a federated credential), sent after that token had expired. Entra returned: > AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T17:08:40.4130764Z, assertion valid from 2026-10-30T16:52:40.0000000Z The lab's record cuts the message at about 160 characters, so the rest of the line is missing here. A user on [Microsoft Q&A](https://learn.microsoft.com/en-us/answers/questions/778031/client-assertion-is-not-within-its-valid-time-rang) posted a full message with the expiry time instead: *"Current time: 2022-03-18T11:28:52.5620799Z, expiry time of assertion 2022-03-15T11:56:47.0000000Z."* A later reply in the same thread quotes both *"assertion valid from"* and *"expiry"*. The exact wording of the second half varies between reports. Either way, compare the times in it with the `nbf` and `exp` of the token you sent. A **client assertion** is a signed token the app sends instead of a client secret. It is either a JWT the app signs with its own certificate, or a token from another identity provider that a federated credential trusts, such as GitHub Actions or Azure DevOps. Microsoft's certificate credentials page describes its time claims. `nbf` is *"the time before which the JWT MUST NOT be accepted"* and `exp` is *"the expiration time on or after which the JWT must not be accepted"*. 700024 means the current time is outside that window. Microsoft does document the code on another page. Its Azure DevOps workload identity troubleshooting page lists: > **AADSTS700024: Client assertion is not within its valid time range** > > If the error happens after approximately 1 hour, use a service connection with Workload identity federation and a Managed Identity instead. [...] If the error happens before 1 hour but after 10 minutes, move commands that (implicitly) request an access token to e.g. access Azure storage to the beginning of your script. ## Reproduced in the lab On 30 October 2026 the lab ran a GitHub Actions job that signs in to my lab tenant through a federated credential. It sent a client-credentials token request with the job's OIDC token as the client assertion, after the token had expired. Entra returned `AADSTS700024`, first line quoted above. An earlier lab run the same day sent the same kind of request about 60 seconds after `exp` and got a token back ([lab run issue](https://github.com/GrantZero604/Brambrinkmeier.com/issues/64)); the run above waited about 11 minutes. Our reading: Entra allows some clock skew. Two runs don't show where the limit is, and Microsoft doesn't publish one. The message gives the current time and the start of the token's validity, 16 minutes apart. That makes it easy to see how old the assertion was. It lands in **`AADServicePrincipalSignInLogs`**: two rows (one per run), Failure. On the failed rows the client credential type is "none", while the app's successful sign-ins show "federatedIdentityCredential", so don't filter on that field to find these. Entra's explanation on the row reads: *"The app used an expired client assertion. It needs to be updated in the Azure Portal to generate a new client secret or certificate."* That advice doesn't fit a federated credential, as far as we can tell; the fix is a fresh assertion, as below. The row's failure reason is a template with placeholders (`{curTime}`, `{validTime}`, `{expTime}`); the real times are only in the error the app got. The KQL below was run on these rows ([how](https://brambrinkmeier.com/methodology/)). The first two queries found the rows. The unfamiliar-IP query returned nothing, which is correct here: both failing IPs also had successful sign-ins. ## Is it an attack? Usually no. It is a timing problem in the app or pipeline. | Pattern | Likely meaning | |---|---| | A GitHub Actions or Azure DevOps job fails partway through, after its first Azure commands worked | The job outlived its federated token. A reply in the Azure/login repository says the GitHub token's *"lifetime of it is 5 mins"* ([issue #441](https://github.com/Azure/login/issues/441)). Users report failures once Azure CLI runs past about 10 minutes ([issue #372](https://github.com/Azure/login/issues/372)). | | Azure DevOps fails after about 1 hour, or between 10 minutes and 1 hour | The two cases Microsoft's DevOps page describes, quoted above. | | An app with a self-signed certificate assertion fails on every request | In Q&A 778031 the expiry in the message stayed days in the past while the user's code set a fresh one. Our reading: the app sends a cached or reused assertion, sets `nbf`/`exp` wrongly, or runs on a host whose clock or time zone is off. A reply in that thread suspects time zones. | | 700024 from an IP that never signs in successfully for that app | Possibly an old assertion replayed from somewhere else (unconfirmed). Entra rejected it, but a leaked token means something leaked. Check where it came from. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 700024 is logged in. An app signing in as itself should land in `AADServicePrincipalSignInLogs` (our lab rows did), but check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "700024" | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, AppId ``` Which apps fail, with which credential type and federated credential. `FederatedCredentialId` is documented as the ID of *"an application's federated identity credential if a federated identity credential was used to sign in"*. Next to the failures, the query counts the same app's successes, which shows whether a job got its first tokens before failing: ```kusto let fails = AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "700024" | summarize Failures = count(), LastFail = max(TimeGenerated), FailIPs = make_set(IPAddress, 10) by AppId, ServicePrincipalName, ClientCredentialType, FederatedCredentialId; let wins = AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "0" | summarize Successes = count() by AppId; fails | join kind=leftouter wins on AppId | project AppId, ServicePrincipalName, ClientCredentialType, FederatedCredentialId, Failures, Successes, LastFail, FailIPs | sort by Failures desc ``` 700024 from IP addresses that never succeed for that app may point to replay. Runners with changing IPs produce false positives, so treat hits as a starting point: ```kusto let goodIPs = AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "0" | distinct AppId, IPAddress; AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "700024" | join kind=leftanti goodIPs on AppId, IPAddress | summarize Attempts = count(), LastSeen = max(TimeGenerated) by AppId, ServicePrincipalName, IPAddress | sort by Attempts desc ``` ## How do I fix AADSTS700024? **For developers:** 1. **GitHub Actions:** request Azure tokens early, or log in again before late steps that need Azure. Users in [issue #372](https://github.com/Azure/login/issues/372) report that Azure CLI does not refresh the ID token on its own. A community workaround there re-runs `az login` with a fresh federated token every 240 seconds. Splitting a long job into shorter jobs should also work, as each job gets its own token. We haven't tested this. 2. **Azure DevOps:** follow Microsoft's two cases quoted above. Past about 1 hour, use workload identity federation with a managed identity. Between 10 minutes and 1 hour, move the commands that need a token to the start of the script, so the cached access token covers the rest. 3. **Self-signed assertions:** build a new assertion for each token request. Microsoft's certificate credentials page says to use the current time for `nbf` and to keep `exp` *"short - 5-10 minutes after `nbf` at most"*. 4. **Clock:** a host clock that runs ahead or behind likely gives the same error even with a fresh assertion (unconfirmed). Keep the clock in sync. **For admins:** 1. Find the app with the queries above and give its owner the time of the failures. 2. Check whether the failures sit late in long pipeline runs. If so, it is the token lifetime, not the federated credential setup. 3. If failures come from IPs your pipelines don't use, find out how the assertion got there. ## Evidence Reproduced in a lab tenant on 2026-10-30 (ROPC and other token-endpoint requests against a lab tenant; scenario: Client assertion expired). First line returned: > AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T17:08:40.4130764Z, assertion valid from 2026-10-30T16:52:40.0000000Z Sign-in log row read: 2026-10-30. KQL run against the exported lab rows: 2026-10-30. Lab-run rows naming this code (7; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Client assertion expired | 700024 | 700024 | AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T21:40:51.4941498Z, assertion valid from 2026-10-30T21:24:51.0000000Z | | 2026-10-30 | Client assertion expired | 700024 | 700024 | AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T22:30:55.4651851Z, assertion valid from 2026-10-30T22:14:55.0000000Z | | 2026-10-30 | Client assertion expired | 700024 | 700024 | AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T22:11:38.3450502Z, assertion valid from 2026-10-30T21:55:38.0000000Z | | 2026-10-30 | Client assertion expired | 700024 | 700024 | AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T23:01:02.2283272Z, assertion valid from 2026-10-30T22:45:02.0000000Z | | 2026-10-30 | Client assertion expired | 700024 | 700024 | AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T23:33:21.4471912Z, assertion valid from 2026-10-30T23:17:21.0000000Z | | 2026-10-30 | Client assertion expired | 700024 | 700024 | AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T17:08:40.4130764Z, assertion valid from 2026-10-30T16:52:40.0000000Z | | 2026-10-31 | Client assertion expired | 700024 | 700024 | AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-31T00:07:21.2184562Z, assertion valid from 2026-10-30T23:51:21.0000000Z | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Troubleshoot an Azure Resource Manager workload identity service connection (Azure DevOps)](https://learn.microsoft.com/en-us/azure/devops/pipelines/release/troubleshoot-workload-identity) 3. [Microsoft identity platform application authentication certificate credentials](https://learn.microsoft.com/en-ca/entra/identity-platform/certificate-credentials) 4. [Microsoft Q&A: Client assertion is not within its valid time range (778031)](https://learn.microsoft.com/en-us/answers/questions/778031/client-assertion-is-not-within-its-valid-time-rang) 5. [Azure/login issue #441 (GitHub)](https://github.com/Azure/login/issues/441) 6. [Azure/login issue #372 (GitHub)](https://github.com/Azure/login/issues/372) 7. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://docs.azure.cn/en-us/azure-monitor/reference/tables/AADServicePrincipalSignInLogs) ## Related codes [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS7000222](https://brambrinkmeier.com/entra/aadsts/7000222/), [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS50013](https://brambrinkmeier.com/entra/aadsts/50013/), [AADSTS50027](https://brambrinkmeier.com/entra/aadsts/50027/), [AADSTS90023](https://brambrinkmeier.com/entra/aadsts/90023/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS700024: Client assertion is not within its valid time range (fix)", https://brambrinkmeier.com/entra/aadsts/700024/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/700051/ # AADSTS700051: Access tokens not enabled for the app (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/700051/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700051.json **Short answer:** AADSTS700051 means an app asked the authorize endpoint for an access token directly (response_type=token, the implicit flow) but its app registration doesn't allow access tokens through the implicit flow. It is a configuration error with low attack value. Microsoft recommends against the implicit flow: move the app to the authorization code flow, or tick Access tokens if you can't yet. **Fix:** User: report the app name to whoever runs it. Developer: move the app to the authorization code flow (`response_type=code`). Admin, only if the app can't move yet: App registrations > the app > Authentication > tick Access tokens under Implicit grant and hybrid flows, then Save. | Field | Value | |---|---| | Code | AADSTS700051 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS700051 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700051 (checked 30 October 2026). In my lab tenant, an unauthenticated authorize request in a browser with `response_type=token`, for an app registration without the implicit grant for access tokens, showed this error on the page: > AADSTS700051: response_type 'token' is not enabled for the application. `response_type=token` is the implicit flow: the app gets an access token straight from the `/authorize` endpoint. Microsoft's implicit grant page says the app registration *"must have the corresponding implicit grant flow enabled, by selecting **ID tokens** and **access tokens** in the **Implicit grant and hybrid flows** section."* 700051 is what the lab got when **Access tokens** was not selected. The same Microsoft page gives a different message for this case: *"If it's not enabled, an `unsupported_response` error will be returned: The provided value for the input parameter 'response_type' is not allowed for this client. Expected value is 'code'"*. The lab got the 700051 text instead. Our reading: the page's example is a different or older message, or comes with a different request. Expect the 700051 wording. Its documented sibling is [AADSTS700054](https://brambrinkmeier.com/entra/aadsts/700054/), the same refusal for `response_type=id_token`, which Microsoft does list. ## Reproduced in the lab In a manual lab test on 30 October 2026, an authorize URL with `response_type=token` for a lab app registration without implicit access tokens was opened in a private browser window, without signing in. Entra showed `AADSTS700051` on its error page with this first line: > AADSTS700051: response_type 'token' is not enabled for the application. That confirms the code and its wording at the authorize endpoint. It also shows the error doesn't need a signed-in user: the request was unauthenticated. It lands in **`SigninLogs`**, logged under the account already signed in to that browser (the lab admin). Entra's explanation on the row reads: *"The application requested an unsupported response type due to the following reasons: response_type 'token' is not enabled for the application. Application owner should go to the Azure portal or call MS Graph to enable the implicit access token grant."* The row shows client app "Mobile Apps and Desktop clients" even though the request came from a browser. The field likely follows the app's registration, not the request, but that is unconfirmed. The KQL below was run on these rows ([how](https://brambrinkmeier.com/methodology/)). The first query found the rows. The `AuditLogs` query isn't tested: the export has no audit rows. ## Is it an attack? No. It is an app that uses a flow its registration doesn't allow. | Pattern | Likely meaning | |---|---| | An older single-page app or a JavaScript library that uses the implicit flow | The registration never had **Access tokens** ticked, or someone unticked it to retire the implicit flow. | | A developer testing in Postman or a script | Users report this on [Microsoft Q&A](https://learn.microsoft.com/en-us/answers/questions/519324/when-trying-to-create-token-for-implicit-flow-gett): sign-in worked in the browser, the implicit token request from Postman failed with 700051. | | An app that worked and now fails | Someone disabled the implicit grant on the registration. Check the audit log (query below). | As far as we can tell, the request is refused before anyone signs in and nothing is issued. Disabling the implicit grant is a hardening step, so a burst of 700051 after a cleanup tells you which apps still depend on it. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 700051 is logged in. In the lab it was logged in `SigninLogs`, under the account that already had a browser session. A request with no session may leave no row at all. Check both user sign-in tables: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "700051" | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, AppId, AppDisplayName ``` If the app used to work, find who changed its registration: ```kusto AuditLogs | where TimeGenerated > ago(90d) | where OperationName == "Update application" | mv-expand Target = TargetResources | where tostring(Target.displayName) == "" | mv-expand Prop = Target.modifiedProperties | project TimeGenerated, Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)), Property = tostring(Prop.displayName), OldValue = tostring(Prop.oldValue), NewValue = tostring(Prop.newValue) | sort by TimeGenerated desc ``` The table reference documents `TargetResources` and `InitiatedBy` only as dynamic columns. The field names inside them and the operation name `Update application` are our reading of how Entra fills them. Look for a property that changed from true to false around the time the errors started. ## How do I fix AADSTS700051? **For the user:** you can't fix this yourself. Report the app name to whoever runs it. **For developers:** move the app to the authorization code flow. Microsoft: *"We strongly recommend that all new applications use the authorization code flow that now supports single-page apps in place of the implicit flow. Existing single-page apps should also migrate to the authorization code flow."* With the code flow the app sends `response_type=code`, and this error goes away without enabling anything. **For admins**, only if the app can't move yet: 1. In the Microsoft Entra admin center, open **App registrations** and select the app. 2. Select **Authentication**. 3. Under **Implicit grant and hybrid flows**, select **Access tokens**, and **ID tokens** too if the app also requests `id_token`. 4. Save. Microsoft is clear that this is a trade-off: *"Microsoft recommends you do not use the implicit grant flow. In most scenarios, more secure alternatives are available and recommended."* Treat enabling it as a temporary exception, and record who owns the migration. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Authorize request in a browser against a lab tenant; scenario: Implicit access token requested, implicit grant not enabled (browser)). First line returned: > AADSTS700051: response_type 'token' is not enabled for the application. Sign-in log row read: 2026-10-30. KQL run against the exported lab rows: 2026-10-30. Lab-run rows naming this code (1; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Implicit access token requested, implicit grant not enabled (browser) | 700051 | 700051 | AADSTS700051: response_type 'token' is not enabled for the application. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and the OAuth 2.0 implicit grant flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-implicit-grant-flow) 3. [Microsoft Q&A: When trying to create token for implicit flow getting AADSTS700051](https://learn.microsoft.com/en-us/answers/questions/519324/when-trying-to-create-token-for-implicit-flow-gett) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 5. [AuditLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/auditlogs) ## Related codes [AADSTS700054](https://brambrinkmeier.com/entra/aadsts/700054/), [AADSTS500113](https://brambrinkmeier.com/entra/aadsts/500113/), [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS700051: Access tokens not enabled for the app (fix)", https://brambrinkmeier.com/entra/aadsts/700051/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/700054/ # AADSTS700054: ID tokens not enabled for the app (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/700054/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700054.json **Short answer:** AADSTS700054 means an app asked the authorize endpoint for an ID token (response_type id_token) but its app registration doesn't allow ID tokens through the implicit or hybrid flow. It is a configuration error with low attack value. Either tick ID tokens in the app registration, or better, move the app to the authorization code flow. **Fix:** User: report the app name and the time to whoever runs the app. Developer: move to the authorization code flow with PKCE. Admin, only if the app must keep the implicit or hybrid flow: App registrations > the app > Authentication > tick ID tokens under Implicit grant and hybrid flows. | Field | Value | |---|---| | Code | AADSTS700054 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS700054 mean? Microsoft's description: > Response_type 'id_token' isn't enabled for the application. The application requested an ID token from the authorization endpoint, but did not have ID token implicit grant enabled. Sign in to the [Microsoft Entra admin center](https://entra.microsoft.com) as at least a [Cloud Application Administrator](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/permissions-reference#cloud-application-administrator) and then browse to **Entra ID** > **App registrations**. Select your application and then select **Authentication**. Under **Implicit grant and hybrid flows**, make sure **ID tokens'** is selected. The app sent `response_type=id_token` (alone, or as `code id_token`) to the `/authorize` endpoint. The app registration says ID tokens may not be returned from that endpoint. Entra refuses before any token is issued. Two flows do this. The implicit flow: Microsoft's implicit grant page says `response_type` *"Must include `id_token` for OpenID Connect sign-in"*, and that the app registration *"must have the corresponding implicit grant flow enabled, by selecting **ID tokens** and **access tokens** in the **Implicit grant and hybrid flows** section."* And the hybrid flow: the authorization code flow page says *"You can also receive an ID token if you request one and have the implicit grant enabled in your application registration. This behavior is sometimes referred to as the hybrid flow."* The protocol error the app sees may be `unsupported_response` or `unsupported_response_type`, depending on the page you read. Microsoft's auth code flow page says that in the hybrid flow `unsupported_response_type` *"signals that you must enable the ID token implicit grant setting on the client app registration."* Our reading: the AADSTS700054 code is the same event, in the `error_codes` field of the response. ## Is it an attack? No. It is a mismatch between what the app asks for and what its registration allows. | Pattern | Likely meaning | |---|---| | One app, all users, starting on a specific day | The app was deployed or reconfigured to use the implicit or hybrid flow, and the registration wasn't updated. Or someone unticked **ID tokens**. | | One app, after someone cleaned up the registration | ID tokens were turned off on purpose, but the app still uses the old flow. | | An app you don't recognise | Possibly someone is using your app's client ID with a different flow (unconfirmed). Check whether the redirect URI and client ID are your own. Still a refusal, not a breach. | As far as we can tell, nothing is issued when this error fires, so there is no token for an attacker to capture. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 700054 is logged in. It happens at the interactive authorize endpoint, so `SigninLogs` is the most likely table (our assumption). Check: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "700054" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Which apps hit it, since when, and from which clients: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "700054" | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Agents = make_set(UserAgent, 5) by AppDisplayName, AppId | sort by Users desc ``` `FirstSeen` is useful: put it next to the app registration's change history in the Entra audit log to see what changed. If the user name is empty in these rows, the error came before the user signed in (our assumption, not yet checked against real data). ## How do I fix AADSTS700054? **For the user:** you can't fix this yourself. Report the app name and the time to whoever runs the app. **For developers:** Microsoft recommends against the flow that needs this setting. The implicit grant page says: *"We strongly recommend that all new applications use the authorization code flow that now supports single-page apps in place of the implicit flow."* For a single-page app, use the authorization code flow with PKCE; the auth code flow page says PKCE is *"required by the Microsoft identity platform for single page apps using the authorization code flow."* MSAL.js 2 and later does this for you. If you really need an ID token from `/authorize` (hybrid flow), ask the app admin to enable **ID tokens**, and include `openid` in `scope` and a `nonce`. **For admins:** 1. Find the app with the second query. 2. Ask the developer which flow the app uses. If it can move to the authorization code flow, do that and leave the implicit setting off. 3. If the app must keep the implicit or hybrid flow: Entra admin center > **Entra ID** > **App registrations** > the app > **Authentication** > **Implicit grant and hybrid flows** > tick **ID tokens**. Tick **Access tokens** only if the app also requests access tokens from `/authorize`. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and the OAuth 2.0 implicit grant flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-implicit-grant-flow) 3. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS54005](https://brambrinkmeier.com/entra/aadsts/54005/), [AADSTS500113](https://brambrinkmeier.com/entra/aadsts/500113/), [AADSTS700051](https://brambrinkmeier.com/entra/aadsts/700051/), [AADSTS9002327](https://brambrinkmeier.com/entra/aadsts/9002327/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS700054: ID tokens not enabled for the app (fix)", https://brambrinkmeier.com/entra/aadsts/700054/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/700081/ # AADSTS700081: Refresh token reached its maximum lifetime (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/700081/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700081.json **Short answer:** AADSTS700081 means the app tried to use a refresh token that is past its maximum lifetime. Users report it in single-page apps, where Microsoft caps refresh tokens at 24 hours. Microsoft's error reference doesn't list it. It is an expected part of the token lifecycle with low attack value. The app must send the user through sign-in again. **Fix:** User: sign in to the app again; a page reload is often enough. Developer: treat it as sign-in needed. With MSAL.js, catch it from `acquireTokenSilent` and fall back to `acquireTokenRedirect` or `acquireTokenPopup`. Admin: nothing to change; the SPA lifetime can't be extended. | Field | Value | |---|---| | Code | AADSTS700081 | | Category | Tokens and sessions | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS700081 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700081 (checked 30 October 2026). The wording below comes from a user report. A developer on the MSAL.js GitHub repository posted: > AADSTS700081: The refresh token has expired due to maximum lifetime. The token was issued on 2021-07-22T15:38:26.0767832+00:00 and the maximum allowed lifetime for this application is 1.00:00:00. The app was a single-page app (SPA) using MSAL.js 2 and MSAL React. It showed up during an `acquireTokenSilent` call. A commenter in the thread said this error should be handled inside `acquireTokenSilent` and not returned to the app. `1.00:00:00` is one day. Microsoft documents the 24-hour cap, without the code number. Its refresh token page: > Refresh tokens sent to a redirect URI registered as `spa` expire after 24 hours. Additional refresh tokens acquired using the initial refresh token carry over that expiration time, so apps must be prepared to rerun the authorization code flow using an interactive authentication to get a new refresh token every 24 hours. The same page lists 24 hours for single-page apps, 24 hours for apps that use the email one-time passcode flow, and 90 days for all other scenarios. So rotating the refresh token doesn't help. Each new refresh token inherits the original expiry. When it passes, the app has to start a new sign-in. Microsoft's error reference lists a code for the same situation, AADSTS700084: *"The refresh token was issued to a single page app (SPA), and therefore has a fixed, limited lifetime of {time}, which can't be extended."* Our reading: 700081 and 700084 describe the same cap. Which code you get in which case isn't documented. The GitHub report is from 2021, so 700084 may be the newer wording. Don't confuse it with [700082](https://brambrinkmeier.com/entra/aadsts/700082/), which is a refresh token that expired from **inactivity**. 700081 is about **total age**, however active the user was. ## Is it an attack? No. It is the token lifecycle working as designed. | Pattern | Likely meaning | |---|---| | SPA users get it once a day | The 24-hour cap. Expected. The app should redirect to sign-in. | | Users see an error page instead of a quiet re-sign-in | Probably the app doesn't handle the error (unconfirmed). | | One user, many rows, no success after | The app keeps retrying the expired token. A bug in the app. | | Expired tokens presented from IPs your users don't use | Possibly someone replaying an old stolen token (unconfirmed). Rare; check the IPs. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 700081 is logged in. Our reading: refresh token redemption is non-interactive, so `AADNonInteractiveUserSignInLogs` is the first place to look. Check where it lands: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType in ("700081", "700084", "700082") | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable, ResultType ``` Which apps, and whether users recover. A user who hits 700081 and never succeeds on the same app that day points at an app that doesn't fall back to sign-in: ```kusto let expired = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "700081" | summarize FirstFail = min(TimeGenerated) by UserPrincipalName, AppId, AppDisplayName; let successes = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "0" | summarize LastSuccess = max(TimeGenerated) by UserPrincipalName, AppId; expired | join kind=leftouter successes on UserPrincipalName, AppId | where isnull(LastSuccess) or LastSuccess < FirstFail | summarize UsersNotRecovering = dcount(UserPrincipalName) by AppDisplayName, AppId | sort by UsersNotRecovering desc ``` Non-interactive rows are aggregated, so counts are not request counts. ## How do I fix AADSTS700081? **For the user:** sign in to the app again. A page reload is often enough. If you see this every day, the app should handle it for you; tell its owner. **For developers:** 1. Treat it as "sign-in needed", not as a failure. Microsoft: *"apps must be prepared to rerun the authorization code flow using an interactive authentication to get a new refresh token every 24 hours."* 2. With MSAL.js, catch the error from `acquireTokenSilent` and fall back to `acquireTokenRedirect` or `acquireTokenPopup`. In the GitHub thread, a commenter said MSAL should fall back to a hidden iframe when the refresh token expires. The reporter's fix was letting the app's page load in an iframe (`X-Frame-Options: SAMEORIGIN`). 3. Expect silent renewal to fail in browsers that block third-party cookies. Microsoft: *"The browser must visit the sign-in page in a top-level frame to show the login session."* 4. If you need refresh tokens that live longer, the client isn't an SPA. Redeem tokens on a backend registered as a **Web** app. Don't move SPA tokens to a server; that gives [9002327](https://brambrinkmeier.com/entra/aadsts/9002327/). **For admins:** nothing to change in the tenant. Microsoft says the SPA lifetime is fixed and *"can't be extended"* (700084 wording). Filter the code out of failure dashboards. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [GitHub: Failed authentication. AADSTS700081: The refresh token has expired due to maximum lifetime (microsoft-authentication-library-for-js #3931)](https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/3931) 3. [Refresh tokens in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) 4. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS70008](https://brambrinkmeier.com/entra/aadsts/70008/), [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/), [AADSTS9002327](https://brambrinkmeier.com/entra/aadsts/9002327/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS700081: Refresh token reached its maximum lifetime (fix)", https://brambrinkmeier.com/entra/aadsts/700081/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/700082/ # AADSTS700082: The refresh token has expired due to inactivity Canonical: https://brambrinkmeier.com/entra/aadsts/700082/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700082.json **Short answer:** AADSTS700082 means an app tried to use a refresh token that expired because nobody used it for too long. Microsoft calls it an expected part of the token lifecycle, so it has low attack value. One useful reading: a stolen refresh token that sat unused long enough fails here too. Hunt it in AADNonInteractiveUserSignInLogs with ResultType == "700082". **Fix:** Nothing to fix: the token expired from inactivity. User: sign in again. Admin: exclude 700082 from failure-rate dashboards. If it comes from an IP you can't explain for that user, check the user's other sign-ins from that IP. | Field | Value | |---|---| | Code | AADSTS700082 | | Microsoft name | ExpiredOrRevokedGrantInactiveToken | | Category | Tokens and sessions | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-25 | ## What does AADSTS700082 mean? Microsoft's description: > **ExpiredOrRevokedGrantInactiveToken**: The refresh token has expired due to inactivity. The token was issued on {issueDate} and was inactive for {time}. Expected part of the token lifecycle - the user went an extended period of time without using the application, so the token was expired when the app attempted to refresh it. A sibling in the same table, **70008 ExpiredOrRevokedGrant**, reads *"The refresh token has expired due to inactivity."* The token wasn't revoked and no policy fired. It sat unused until it expired. The message tells you when it was issued and how long it was inactive. ## Is it an attack? See the [comparison of the codes behind "asked to sign in again"](https://brambrinkmeier.com/guides/why-user-asked-to-sign-in-again-entra-id/) (70043, 700082, 50173, 50133, 50076). No. Microsoft's own description says it is *"Expected part of the token lifecycle"*. Typical sources are a laptop that was off for weeks, an app the user rarely opens, or a phone that came back from a drawer. | Pattern | Likely meaning | |---|---| | 700082 from a user's known device, then an interactive success | The user came back to an app after a long break. Benign. | | 700082 from an IP or device the user hasn't used recently | Someone presented an old refresh token from an unfamiliar place. Reasoning, not a documented detection: if that token was stolen, the expiry is what stopped it. Worth a short look. | | Steady 700082 from a service or shared device | A client that holds tokens but rarely uses them. Configuration, not attack. | **The useful negative example:** a stolen refresh token is only valuable while it is used. One that the attacker left dormant long enough fails with 700082 rather than giving them access. That is the token lifetime working in your favour, not a detection you can rely on. **IP caveat for confidential clients.** Microsoft's [non-interactive sign-ins page](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) says: *"The IP address of non-interactive sign-ins performed by confidential clients doesn't match the actual source IP of where the refresh token request is coming from. Instead, it shows the original IP used for the original token issuance."* So an unfamiliar IP on a 700082 row is a meaningful signal mainly for public clients (desktop, mobile and browser apps). For confidential clients it may only show where the token was first issued, and the second query below inherits that limit. ## How do I find it in my logs (KQL)? Baseline by app: ```kusto AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "700082" | summarize Rows = count(), Users = dcount(UserPrincipalName) by AppDisplayName | sort by Rows desc ``` 700082 from an IP where the same user had no successful sign-in in the previous 30 days: ```kusto let lookback = 30d; let knownUserIPs = union (SigninLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType), (AADNonInteractiveUserSignInLogs | project TimeGenerated, UserPrincipalName, IPAddress, ResultType) | where TimeGenerated > ago(lookback) | where ResultType == "0" | distinct UserPrincipalName, IPAddress; AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "700082" | join kind=leftanti knownUserIPs on UserPrincipalName, IPAddress | extend Device = parse_json(DeviceDetail), Location = parse_json(LocationDetails) | project TimeGenerated, UserPrincipalName, IPAddress, Country = tostring(Location.countryOrRegion), OS = tostring(Device.operatingSystem), AppDisplayName, UserAgent, ResultDescription | sort by TimeGenerated desc ``` Expect some benign hits here: a user who was away for more than the lookback period has no recent "known" IPs to match. `ResultType` is a **string** column, so compare it with `"700082"`, not `700082`. `DeviceDetail` and `LocationDetails` are strings in this table, hence `parse_json`. ## How does Conditional Access affect it? - No Conditional Access policy causes 700082. It is token inactivity, not a session control. If a sign-in frequency policy refused the token, you would see [70043](https://brambrinkmeier.com/entra/aadsts/70043/) instead. - The interactive sign-in that follows goes through MFA and Conditional Access as normal. ## How do I fix AADSTS700082? **For the user:** sign in again. **For admins:** 1. Nothing to fix. Exclude 700082 from failure-rate dashboards, or it inflates them. 2. If the second query returns an IP you can't explain for a user, check that user's other sign-ins from it. A token that failed here may have a sibling that didn't. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. Lab-run rows naming this code (3; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Refresh token after the admin revoked sessions | 50173 / 700082 / 50076 | 50173 | AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. The gran | | 2026-10-31 | Refresh token after the admin revoked sessions | 50173 / 700082 / 50076 | 50173 | AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. The gran | | 2026-10-31 | Refresh token after the admin revoked sessions | 50173 / 700082 / 50076 | 50173 | AADSTS50173: The provided grant has expired due to it being revoked, a fresh auth token is needed. The user might have changed or reset their password. The gran | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 3. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadnoninteractiveusersigninlogs) ## Related codes [AADSTS70043](https://brambrinkmeier.com/entra/aadsts/70043/), [AADSTS50173](https://brambrinkmeier.com/entra/aadsts/50173/), [AADSTS50133](https://brambrinkmeier.com/entra/aadsts/50133/), [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/), [AADSTS50089](https://brambrinkmeier.com/entra/aadsts/50089/), [AADSTS50196](https://brambrinkmeier.com/entra/aadsts/50196/), [AADSTS54005](https://brambrinkmeier.com/entra/aadsts/54005/), [AADSTS70008](https://brambrinkmeier.com/entra/aadsts/70008/), [AADSTS70044](https://brambrinkmeier.com/entra/aadsts/70044/), [AADSTS700081](https://brambrinkmeier.com/entra/aadsts/700081/), [AADSTS7000110](https://brambrinkmeier.com/entra/aadsts/7000110/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS700082: The refresh token has expired due to inactivity", https://brambrinkmeier.com/entra/aadsts/700082/ (CC BY 4.0), last updated 2026-10-25. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/700211/ # AADSTS700211: Federated credential issuer doesn't match (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/700211/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700211.json **Short answer:** AADSTS700211 means a workload sent an external token whose issuer matches none of the federated identity credentials on the app or managed identity. Usually the credential has the wrong issuer URL (a typo, a trailing slash, the wrong cluster or Azure DevOps issuer), or no credential exists for that provider. It is a configuration error with low attack value. **Fix:** Pipeline owner: read the issuer from the error message or the token's `iss` claim, and set the federated credential's issuer to exactly that string: same case, same trailing slash, no spaces. Azure DevOps: edit and save the service connection. Kubernetes: use the cluster's own OIDC issuer URL. | Field | Value | |---|---| | Code | AADSTS700211 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS700211 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700211 (checked 30 October 2026). Microsoft's Azure DevOps troubleshooting page does: > **AADSTS700211: No matching federated identity record found for presented assertion issuer** > No federated credential was created or the issuer URL is not correct. Users report that the full message names the issuer from the token and adds a hint. From a GitHub issue on the azure-workload-identity project: > AADSTS700211: No matching federated identity record found for presented assertion issuer '``'. Please check your federated identity credential Subject, Audience and Issuer against the presented assertion. A federated identity credential trusts tokens from one issuer. Microsoft's restrictions page: the issuer *"is the URL of the external identity provider and must match the `issuer` claim of the external token being exchanged"*, and *"If the `issuer` claim has leading or trailing whitespace in the value, the token exchange is blocked."* Microsoft announced case-sensitive matching in August 2024 and rolled it out in stages (see [7002138](https://brambrinkmeier.com/entra/aadsts/7002138/)). 700211 looks like the issuer-specific form of [70021](https://brambrinkmeier.com/entra/aadsts/70021/); Microsoft doesn't say so. Its siblings are [700212](https://brambrinkmeier.com/entra/aadsts/700212/) (audience) and [700213](https://brambrinkmeier.com/entra/aadsts/700213/) (subject). If the app has no federated credentials at all, you get [70025](https://brambrinkmeier.com/entra/aadsts/70025/). Microsoft doesn't document the order in which the three values are checked. ## Reproduced in the lab On 30 October 2026 an automated lab run set this up in my own tenant: one app registration presents its access token as a client assertion, and a second app carries the federated identity credential that is supposed to accept it. With the credential's **issuer** set to a different URL than the token's, Entra returned `AADSTS700211`: > AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com//v2.0'. The issuer in the message is the one Entra read from the token, not the one on your credential. Compare it character for character with what the credential has. The sign-in log row isn't captured yet; see [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? Usually not. | Pattern | Likely meaning | |---|---| | A new federation setup fails on the first run | The issuer on the credential differs from the token's `iss`: a typo, a missing or extra trailing slash, or the wrong URL for the platform. | | Azure DevOps fails after converting or recreating a service connection | The credential still holds the other Azure DevOps issuer. Microsoft lists two: `https://vstoken.dev.azure.com/` and `https://login.microsoftonline.com//v2.0` for new connections. | | Kubernetes fails after a cluster was rebuilt or the workload moved to another cluster | Each cluster has its own OIDC issuer URL. Likely the credential still points at the old one. | | Failures for your app from an issuer and IP you don't use | Someone presenting a token from their own provider with your app's client ID. Our reading: it fails because nothing trusts that issuer. Check, but it is not an incident on its own. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 700211 lands in. Our reading: app registration failures land in `AADServicePrincipalSignInLogs`, and a user-assigned managed identity may log in the separate managed identity sign-in log, which Microsoft says holds managed identity sign-ins *"only"*. Check where it lands in your tenant: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "700211" or ResultSignature == "700211" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable ``` Failures per app, with the error text and source IPs. `ResultDescription` is documented as *"the error description for the sign-in operation"*. Whether it carries the issuer the way the returned message does is our assumption; check a row: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "700211" or ResultSignature == "700211" | summarize Failures = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Descriptions = make_set(ResultDescription, 5), IPs = make_set(IPAddress, 10) by AppId, ServicePrincipalName | sort by Failures desc ``` An app that fails from many IPs you don't own, with an issuer you never configured, is the one to look at. That threshold is a judgement call, not a rule. ## How do I fix AADSTS700211? **For developers and pipeline owners:** 1. Get the issuer from the error message, or decode your provider's token and read `iss`. 2. Set the credential's issuer to exactly that string: same case, same trailing slash, no spaces. Microsoft's create-trust page shows the GitHub issuer both as `https://token.actions.githubusercontent.com` and with a trailing slash, so go by your token. 3. Kubernetes: use the cluster's own OIDC issuer URL. Microsoft's example looks like `https://aksoicwesteurope.blob.core.windows.net//`. 4. Azure DevOps: Microsoft says *"You can fix the issuer URL by editing and then saving a service connection. If Azure DevOps didn't create your identity, you must manually update the issuer."* The correct issuer is shown in the service connection's edit dialog. **For admins:** 1. List the federated credentials on the app or managed identity and compare the issuers with the token. An app can hold at most 20. 2. If the issuer in the failures belongs to a provider you never set up, confirm no credential trusts it and review who can edit the app registration. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Client-credentials token request with a federated identity credential, against a lab tenant; scenario: Federated credential: issuer does not match). First line returned: > AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com//v2.0'. Lab-run rows naming this code (5; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Federated credential: issuer does not match | 700211 / 70021 | 700211 | AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id} | | 2026-10-30 | Federated credential: issuer does not match | 700211 / 70021 | 700211 | AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id} | | 2026-10-30 | Federated credential: issuer does not match | 700211 / 70021 | 700211 | AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id} | | 2026-10-31 | Federated credential: issuer does not match | 700211 / 70021 | 700211 | AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id} | | 2026-10-31 | Federated credential: issuer does not match | 700211 / 70021 | 700211 | AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id} | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/lb-lu/entra/identity-platform/reference-error-codes) 2. [Troubleshoot an Azure Resource Manager workload identity service connection (Azure DevOps)](https://learn.microsoft.com/en-us/azure/devops/pipelines/release/troubleshoot-workload-identity) 3. [Important considerations and restrictions for federated identity credentials](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-considerations) 4. [Configure an app to trust an external identity provider](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust) 5. [Federated identity credentials and case-sensitive matching (Microsoft Entra breaking changes, August 2024)](https://learn.microsoft.com/en-us/entra/identity-platform/reference-breaking-changes) 6. [azure-workload-identity issue 1613 (GitHub)](https://github.com/Azure/azure-workload-identity/issues/1613) 7. [What are service principal sign-ins in Microsoft Entra?](https://learn.microsoft.com/en-my/entra/identity/monitoring-health/concept-service-principal-sign-ins) 8. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS70021](https://brambrinkmeier.com/entra/aadsts/70021/), [AADSTS700212](https://brambrinkmeier.com/entra/aadsts/700212/), [AADSTS700213](https://brambrinkmeier.com/entra/aadsts/700213/), [AADSTS7002138](https://brambrinkmeier.com/entra/aadsts/7002138/), [AADSTS70025](https://brambrinkmeier.com/entra/aadsts/70025/), [AADSTS700226](https://brambrinkmeier.com/entra/aadsts/700226/), [AADSTS7002121](https://brambrinkmeier.com/entra/aadsts/7002121/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS700211: Federated credential issuer doesn't match (fix)", https://brambrinkmeier.com/entra/aadsts/700211/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/700212/ # AADSTS700212: Federated credential audience doesn't match (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/700212/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700212.json **Short answer:** AADSTS700212 means a workload sent an external token whose audience (aud claim) matches none of the federated identity credentials on the app or managed identity. Usually the token was requested for the wrong audience, for example a Kubernetes token not projected for api://AzureADTokenExchange. It is a configuration error with low attack value. **Fix:** Pipeline owner: read the audience from the error or the token's `aud` claim, and request the token for `api://AzureADTokenExchange` (or the credential's value, same case). Kubernetes: use a projected service account token with that audience. GitHub Actions: leave `audience` at its default. | Field | Value | |---|---| | Code | AADSTS700212 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS700212 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700212 (checked 30 October 2026). We found no other Microsoft page that names it either, so the wording below comes from user reports. A user on Microsoft Q&A, running a workload on Azure Kubernetes Service, posted this response (cluster values shortened): > AADSTS700212: No matching federated identity record found for presented assertion audience '`https://uaenorth.oic.prod-aks.azure.com///,https://.hcp.uaenorth.azmk8s.io,...`'. Please note that the matching is done using a case-sensitive comparison. Please check your federated identity credential Subject, Audience and Issuer against the presented assertion. The response had `"error":"invalid_client"`. The audience the user's token carried was the cluster's own URLs, not `api://AzureADTokenExchange`. What Microsoft does document is the audience rule. A federated identity credential lists the audience Entra accepts. Microsoft's Graph overview: it *"says what Microsoft identity platform should accept in the `aud` claim in the incoming token"* and *"should be set to `api://AzureADTokenExchange` for Microsoft Entra ID"*. The restrictions page: *"You must add a single audience value"*. Matching is case-sensitive. 700212 looks like the audience-specific form of [70021](https://brambrinkmeier.com/entra/aadsts/70021/); Microsoft doesn't say so. Its siblings are [700211](https://brambrinkmeier.com/entra/aadsts/700211/) (issuer) and [700213](https://brambrinkmeier.com/entra/aadsts/700213/) (subject); [70025](https://brambrinkmeier.com/entra/aadsts/70025/) means the app has no federated credentials at all. **A lab test on 30 October 2026 returned a different code for this case.** With a federated credential whose audience didn't match the presented token, my lab tenant answered with [`AADSTS7002121`](https://brambrinkmeier.com/entra/aadsts/7002121/), not 700212: > AADSTS7002121: No matching federated identity record found for presented assertion audience ''. The Audience for the federated identity credential... In the same run, a wrong issuer gave [700211](https://brambrinkmeier.com/entra/aadsts/700211/) and a wrong subject gave [700213](https://brambrinkmeier.com/entra/aadsts/700213/), so those two are confirmed. For the audience, 7002121 is what Entra returns today on a current tenant. We can't tell from one tenant whether 700212 is an older code, a different-cloud code, or tied to a particular issuer; the user report above is real and recent, so both appear to exist. If you are writing a detection, match on both. See [7002121](https://brambrinkmeier.com/entra/aadsts/7002121/) for the lab-reproduced page. ## Is it an attack? No. It means the workload asked its own provider for a token meant for something else. | Pattern | Likely meaning | |---|---| | Kubernetes pod fails and the audience in the error is the cluster URL | The pod is using its default service account token, not a token projected for `api://AzureADTokenExchange`. Users report this; the Q&A thread above is one case. | | GitHub Actions fails after changing the `audience` input | The workflow asks GitHub for a token with an audience that the credential doesn't list. The Azure/login README: *"The default `audience` is `api://AzureADTokenExchange`."* | | A non-public Azure cloud | The Azure/login README notes that for non-public clouds *"the `audience` will also need to be updated."* Presumably the credential and the workflow must agree on the cloud's value. | | Case differs only (`api://azureadtokenexchange`) | Microsoft has moved to case-sensitive matching in stages since 2024. Fix the case on whichever side is wrong. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 700212 lands in. Our reading: app registration failures land in `AADServicePrincipalSignInLogs`; a user-assigned managed identity may log in the managed identity sign-in log instead. Check: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "700212" or ResultSignature == "700212" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable ``` Failures per app with the error text. Whether `ResultDescription` (documented as *"the error description for the sign-in operation"*) carries the presented audience is our assumption; check a row: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "700212" or ResultSignature == "700212" | summarize Failures = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Descriptions = make_set(ResultDescription, 5), IPs = make_set(IPAddress, 10) by AppId, ServicePrincipalName | sort by Failures desc ``` ## How do I fix AADSTS700212? **For developers and pipeline owners:** 1. Read the audience from the error message, or decode the token your workload sends and read `aud`. 2. Make the workload request its token for `api://AzureADTokenExchange`, unless you deliberately chose another value. Microsoft: *"For security reasons, you should pick a value that is unique for tokens meant for Microsoft Entra ID."* 3. Kubernetes: the token Entra receives must be a projected service account token with that audience. The answer in the Q&A thread shows a projected volume with `audience: api://AzureADTokenExchange`, mounted at `/var/run/secrets/azure/tokens`. The same answer says the workload identity webhook should inject this when workload identity is enabled. If the mount is missing, check that first. 4. GitHub Actions: leave the `audience` input of `azure/login` at its default unless the credential says otherwise. **For admins:** 1. Check the credential's audience. It holds exactly one value, and Microsoft recommends `api://AzureADTokenExchange`. 2. If you changed it from the default, make sure every workload that uses the credential requests that same value, in the same case. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. Lab-run rows naming this code (5; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-31 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-31 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/lb-lu/entra/identity-platform/reference-error-codes) 2. [Migration to Workflow credential identity is throwing error (Microsoft Q&A)](https://learn.microsoft.com/en-ca/answers/questions/2006914/migration-to-workflow-credential-identity-is-throw) 3. [Important considerations and restrictions for federated identity credentials](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-considerations) 4. [Overview of federated identity credentials (Microsoft Graph)](https://learn.microsoft.com/graph/api/resources/federatedidentitycredentials-overview) 5. [Configure an app to trust an external identity provider](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust) 6. [Federated identity credentials and case-sensitive matching (Microsoft Entra breaking changes, August 2024)](https://learn.microsoft.com/en-us/entra/identity-platform/reference-breaking-changes) 7. [Azure/login GitHub Action README](https://github.com/Azure/login#readme) 8. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS7002121](https://brambrinkmeier.com/entra/aadsts/7002121/), [AADSTS70021](https://brambrinkmeier.com/entra/aadsts/70021/), [AADSTS700211](https://brambrinkmeier.com/entra/aadsts/700211/), [AADSTS700213](https://brambrinkmeier.com/entra/aadsts/700213/), [AADSTS7002138](https://brambrinkmeier.com/entra/aadsts/7002138/), [AADSTS70025](https://brambrinkmeier.com/entra/aadsts/70025/), [AADSTS700226](https://brambrinkmeier.com/entra/aadsts/700226/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS700212: Federated credential audience doesn't match (fix)", https://brambrinkmeier.com/entra/aadsts/700212/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/700213/ # AADSTS700213: Federated credential subject doesn't match (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/700213/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700213.json **Short answer:** AADSTS700213 means a workload sent an external token whose subject matches none of the federated identity credentials on the app or managed identity. Typical causes: a GitHub job that uses an environment while the credential trusts a branch, a renamed repo or service account, or a typo. Microsoft says the same message is also used for issuer and audience mismatches. Low attack value. **Fix:** Pipeline owner: copy the subject from the error message and set the federated credential's subject to exactly that string. Also compare issuer and audience. GitHub: a job with `environment:` needs an Environment credential. Kubernetes: `system:serviceaccount::`. | Field | Value | |---|---| | Code | AADSTS700213 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS700213 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700213 (checked 30 October 2026). Microsoft documents it on other pages. The Azure DevOps troubleshooting page: > **AADSTS700213: No matching federated identity record found for presented assertion subject** > No federated credential was created or the subject is not correct. Microsoft's breaking-change notice from August 2024 gives the full message template: > AADSTS700213: No matching federated identity record found for presented assertion subject '{subject}'. Please note that matching is done using a case-sensitive comparison. Check your federated identity credential Subject, Audience, and Issuer against the presented assertion. It adds two things that matter. First, `'{subject}'` *"provides the value of the subject claim contained in the token being sent from the external IdP"*, so the error tells you what the token said. Second: *"This error template is also used for case-insensitive failures surrounding `issuer` and `audience` validation."* So 700213 doesn't always mean the subject is the problem. Check all three values. Users see shorter variants too. A Microsoft Q&A post from April 2025 quoted *"…presented assertion subject '103432211958501047059'. Check your federated identity credential Subject, Audience and Issuer against the presented assertion."* without the case-sensitivity sentence. Background: a federated identity credential trusts one subject from one issuer. The subject identifies the workload: a GitHub repo plus branch, environment or pull request; a Kubernetes service account; an Azure DevOps service connection; a Google service account ID. Microsoft's create-trust page: *"The values must exactly match the configuration"*. 700213 looks like the subject-specific form of [70021](https://brambrinkmeier.com/entra/aadsts/70021/); Microsoft doesn't say so. Its siblings are [700211](https://brambrinkmeier.com/entra/aadsts/700211/) (issuer) and [700212](https://brambrinkmeier.com/entra/aadsts/700212/) (audience). When the subject is right apart from letter case, the Azure/login README and user reports show [7002138](https://brambrinkmeier.com/entra/aadsts/7002138/) instead. If the app has no federated credentials at all, you get [70025](https://brambrinkmeier.com/entra/aadsts/70025/). ## Reproduced in the lab On 30 October 2026 an automated lab run set this up in my own tenant: one app registration presents its access token as a client assertion, and a second app carries the federated identity credential that is supposed to accept it. With the credential's **subject** set to a value the token doesn't carry, Entra returned `AADSTS700213`: > AADSTS700213: No matching federated identity record found for presented assertion subject ''. As with the issuer, the subject printed is the one from the token. Copy it from the message into the credential rather than typing it out. The sign-in log row isn't captured yet; see [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? No. It is almost always a subject that doesn't match. | Pattern | Likely meaning | |---|---| | GitHub: the subject in the error ends in `:environment:` but the credential trusts a branch | The job declares an `environment`. Microsoft's create-trust page uses `repo:/:environment:` for jobs tied to an environment, and `:ref:` only for jobs that aren't. A Q&A post shows exactly this mismatch (it has no answer). | | GitHub: the credential was made in the portal and includes `@` after the org or repo | The Azure/login README: portal subjects of the form `repo:@/@:...` never match, because *"The OIDC token GitHub sends does **not** include those numeric IDs"*. | | GitHub: one credential per branch, and a new branch, tag or pull request fails | Microsoft: *"Pattern matching isn't supported for branches and tags."* Each one needs its own credential, or a flexible credential (preview, below). | | Azure DevOps: worked before, fails after a rename | Microsoft lists renaming the organization, project or service connection as a cause, for the `sc://` subject. | | The subject looks identical | Look for an invisible difference. In the April 2025 Q&A case above, a moderator reported that a trailing full stop in the credential's subject was the cause. Letter case gives [7002138](https://brambrinkmeier.com/entra/aadsts/7002138/). | | Failures for your app with a subject from a repo or account you don't own | Someone presenting their own token with your app's client ID. Our reading: it fails because nothing trusts that subject. Check, but it is not an incident on its own. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 700213 lands in. Our reading: app registration failures land in `AADServicePrincipalSignInLogs`; a user-assigned managed identity may log in the managed identity sign-in log instead. Check: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "700213" or ResultSignature == "700213" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable ``` Failures per app, with the error text. If `ResultDescription` holds the same text as the returned message (our assumption; check a row), it shows the subject the token presented: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "700213" or ResultSignature == "700213" | summarize Failures = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Descriptions = make_set(ResultDescription, 5), IPs = make_set(IPAddress, 10) by AppId, ServicePrincipalName | sort by Failures desc ``` For an app that worked before, check whether its federated credentials were changed. A third-party write-up (trackr.live) reports this logs as `Update application` with a modified property `FederatedIdentityCredentials`; Microsoft doesn't document that name on the pages we checked: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where OperationName == "Update application" | mv-expand Target = TargetResources | mv-expand Prop = Target.modifiedProperties | where tostring(Prop.displayName) == "FederatedIdentityCredentials" | project TimeGenerated, App = tostring(Target.displayName), Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)), OldValue = tostring(Prop.oldValue), NewValue = tostring(Prop.newValue) ``` ## How do I fix AADSTS700213? **For developers and pipeline owners:** 1. Copy the subject from the error message. In GitHub Actions, the Azure/login README says the run log shows it under `Federated token details` as `subject claim`. 2. Set the credential's subject to exactly that string. The README: *"set the federated credential Subject to exactly match the `subject claim`"*. 3. Also compare the issuer and audience, because Microsoft uses this message for those failures too. 4. GitHub: pick the entity type that matches the job. A job with `environment:` needs an **Environment** credential. A job without one needs **Branch** or **Tag** with the exact ref. Pull request runs need `repo:/:pull-request`. 5. Kubernetes: the subject is `system:serviceaccount::`. A renamed namespace or service account needs a new credential. **For admins:** 1. Azure DevOps after a rename: Microsoft names the cause but gives no fix. Update the subject on the identity to the new `sc://` value. 2. Many branches: an app or user-assigned managed identity holds at most 20 federated credentials, and wildcards aren't supported in ordinary credentials. Microsoft's flexible federated identity credential (preview) uses a `claimsMatchingExpression` such as `claims['sub'] matches 'repo:contoso/contoso-repo:ref:refs/heads/*'` and supports issuers *"such as GitHub, GitLab, and Terraform Cloud"*. It is a preview; weigh that before relying on it. 3. Don't widen trust to make an error go away. A subject that matches more branches or environments than needed would let more workflows act as the app. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Client-credentials token request with a federated identity credential, against a lab tenant; scenario: Federated credential: subject does not match). First line returned: > AADSTS700213: No matching federated identity record found for presented assertion subject ''. Check your federated identity credential Subject. Lab-run rows naming this code (15; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Federated credential: subject does not match | 700213 / 70021 | 700213 | AADSTS700213: No matching federated identity record found for presented assertion subject '{guid}'. Check your federated identity | | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-30 | Federated credential: subject differs only by case | 7002138 / 700213 | 7002138 | AADSTS7002138: No matching federated identity record found for presented assertion subject '{guid}'. The subject matches with case | | 2026-10-30 | Federated credential: subject does not match | 700213 / 70021 | 700213 | AADSTS700213: No matching federated identity record found for presented assertion subject '{guid}'. Check your federated identity | | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-30 | Federated credential: subject differs only by case | 7002138 / 700213 | 7002138 | AADSTS7002138: No matching federated identity record found for presented assertion subject '{guid}'. The subject matches with case | | 2026-10-30 | Federated credential: subject does not match | 700213 / 70021 | 700213 | AADSTS700213: No matching federated identity record found for presented assertion subject '{guid}'. Check your federated identity | | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-30 | Federated credential: subject differs only by case | 7002138 / 700213 | 7002138 | AADSTS7002138: No matching federated identity record found for presented assertion subject '{guid}'. The subject matches with case | | 2026-10-31 | Federated credential: subject does not match | 700213 / 70021 | 700213 | AADSTS700213: No matching federated identity record found for presented assertion subject '{guid}'. Check your federated identity | | 2026-10-31 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-31 | Federated credential: subject differs only by case | 7002138 / 700213 | 7002138 | AADSTS7002138: No matching federated identity record found for presented assertion subject '{guid}'. The subject matches with case | | 2026-10-31 | Federated credential: subject does not match | 700213 / 70021 | 700213 | AADSTS700213: No matching federated identity record found for presented assertion subject '{guid}'. Check your federated identity | | 2026-10-31 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-31 | Federated credential: subject differs only by case | 7002138 / 700213 | 7002138 | AADSTS7002138: No matching federated identity record found for presented assertion subject '{guid}'. The subject matches with case | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/lb-lu/entra/identity-platform/reference-error-codes) 2. [Federated identity credentials and case-sensitive matching (Microsoft Entra breaking changes, August 2024)](https://learn.microsoft.com/en-us/entra/identity-platform/reference-breaking-changes) 3. [Troubleshoot an Azure Resource Manager workload identity service connection (Azure DevOps)](https://learn.microsoft.com/en-us/azure/devops/pipelines/release/troubleshoot-workload-identity) 4. [Azure/login GitHub Action README](https://github.com/Azure/login#readme) 5. [Configure an app to trust an external identity provider](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust) 6. [Set up a flexible federated identity credential (preview)](https://learn.microsoft.com/en-us/entra/workload-id/workload-identities-set-up-flexible-federated-identity-credential) 7. [azure/login@v2 GitHub Action with federated identity (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/2074191/azure-login@v2-github-action-with-federated-identi) 8. [WIF doesn't work from GCP Composer/Airflow's service account (Microsoft Q&A)](https://learn.microsoft.com/en-gb/answers/questions/2244862/wif-doesnt-work-from-gcp-composer-airflows-service) 9. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) 10. [A Federated Identity Credential Adds No Secret (trackr.live, third-party)](https://www.trackr.live/?p=1229) ## Related codes [AADSTS7002138](https://brambrinkmeier.com/entra/aadsts/7002138/), [AADSTS70021](https://brambrinkmeier.com/entra/aadsts/70021/), [AADSTS700211](https://brambrinkmeier.com/entra/aadsts/700211/), [AADSTS700212](https://brambrinkmeier.com/entra/aadsts/700212/), [AADSTS70025](https://brambrinkmeier.com/entra/aadsts/70025/), [AADSTS700226](https://brambrinkmeier.com/entra/aadsts/700226/), [AADSTS7002121](https://brambrinkmeier.com/entra/aadsts/7002121/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS700213: Federated credential subject doesn't match (fix)", https://brambrinkmeier.com/entra/aadsts/700213/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/700226/ # AADSTS700226: Only managed identity tokens work with the Entra ID issuer (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/700226/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/700226.json **Short answer:** AADSTS700226 means a federated identity credential whose issuer is a Microsoft Entra tenant was presented with a token that is not a managed identity token. Microsoft's error reference doesn't list it. The Entra ID issuer exists for the managed identity scenario only, so you can't federate one app registration to another this way. Low attack value. **Fix:** Present a user-assigned managed identity token, with the credential subject set to that managed identity Object (Principal) ID in the same tenant. To let one app registration call another, use a client secret, a certificate, or on-behalf-of instead. | Field | Value | |---|---| | Code | AADSTS700226 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | Where to look | `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS700226 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700226 (checked 30 October 2026). The wording below is from a lab run: > AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer. A public repository of federated-credential experiments records the same line, with the trigger: *"AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer." (when trying to use tokens from app registration to another app registration)*. "MSI" is managed service identity, the older name for a managed identity. "AAD issuer" means a federated identity credential whose issuer is a Microsoft Entra tenant itself, in the form `https://login.microsoftonline.com//v2.0`, rather than GitHub, Kubernetes or another external provider. ### Why this is worth knowing Workload identity federation lets an app registration accept a token from somewhere else instead of holding a secret. One of its configurations uses Entra as the issuer. Microsoft documents that configuration for exactly one case: an app registration trusting a **managed identity**. From Microsoft's page on configuring an app to trust a managed identity: - *"issuer is the URL of the Microsoft Entra tenant's Authority URL in the form `https://login.microsoftonline.com/{tenant}/v2.0`. Both the Microsoft Entra app and managed identity must belong to the same tenant."* - The issuer field in the portal is described as *"the OAuth 2.0 / OIDC issuer URL of the Microsoft Entra ID authority that issues the managed identity token. This value is automatically populated with the current Entra tenant issuer."* - *"subject: This is the case-sensitive GUID of the managed identity's Object (Principal) ID assigned to the Azure workload."* - *"Select managed identity: Click on this link to select the managed identity that will act as the federated identity credential. You can only use User-Assigned Managed Identities as a credential."* Our reading: 700226 is the runtime half of that restriction. The configuration will accept an Entra issuer and a subject GUID, so nothing stops you entering another app registration's service principal object ID and expecting that app's own token to be exchanged. At token time Entra checks the presented token's type and refuses it. So **app registration to app registration federation through the Entra issuer does not work**, however correct the issuer, subject and audience look. Microsoft's pages describe the managed identity case and do not state the refusal, which is why the error has no documented wording. This matters if you were planning to give one app registration access to another tenant's or another app's resources without a secret. The supported routes are a client secret, a certificate credential, an external identity provider as the issuer, or on-behalf-of for a user's token. The siblings cover the other federated failures: [70025](https://brambrinkmeier.com/entra/aadsts/70025/) (no credential at all), [700211](https://brambrinkmeier.com/entra/aadsts/700211/) (issuer), [700213](https://brambrinkmeier.com/entra/aadsts/700213/) (subject), [7002121](https://brambrinkmeier.com/entra/aadsts/7002121/) and [700212](https://brambrinkmeier.com/entra/aadsts/700212/) (audience). 700226 is different in kind: the three values matched and the token was still refused. ## Reproduced in the lab On 30 October 2026 an automated lab run configured a federated identity credential on an app registration, using the lab tenant itself as the issuer (`https://login.microsoftonline.com//v2.0`), and presented a normal app token in a client-credentials request. The run expected a token, because the credential's issuer, subject and audience were the ones the presented token carried. Entra returned: > AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer. The run calls this scenario "Federated credential matches", and that is what makes the code useful: in the same run a mismatch on one of the three values gave [700211](https://brambrinkmeier.com/entra/aadsts/700211/), [700213](https://brambrinkmeier.com/entra/aadsts/700213/) or [7002121](https://brambrinkmeier.com/entra/aadsts/7002121/). 700226 is what Entra returns when those three match and the token is still the wrong kind. The lab did not test the supported arrangement, so it confirms the refusal, not that a managed identity token would have been accepted. No sign-in log row was captured. See [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? No. It is a design limit being hit by a configuration someone built on purpose. | Pattern | Likely meaning | |---|---| | A new integration fails on its first run, with issuer, subject and audience all verified correct | Someone federated one app registration to another. That is what 700226 refuses. | | A workload that used to work starts failing | The workload now presents an app token instead of its managed identity token, for example after moving off an Azure host or switching to a client secret in configuration. | | The subject in the credential is a service principal object ID rather than a managed identity's Object (Principal) ID | The credential points at the wrong principal. Only a user-assigned managed identity works here. | Our reading on the security side: 700226 is a refusal, so a row means the exchange did not happen. It is worth noticing if you did not configure an Entra-issuer credential at all, because someone added a federated credential to one of your apps. Credential additions are in the audit log, not the sign-in log. ## How do I find it in my logs (KQL)? Which table 700226 lands in is undocumented. Our reading: the app registration whose credential was used is the one signing in, so `AADServicePrincipalSignInLogs` is the likely place. Check with a union first: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs, AADManagedIdentitySignInLogs | where TimeGenerated > ago(30d) | where ResultType == "700226" or ResultSignature == "700226" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable ``` The filter covers both columns because the tables document them differently: in `SigninLogs`, `ResultType` *"provides the 5-6 digit error code"*, while in `AADServicePrincipalSignInLogs` it is described as *"Success or Failure"* and `ResultSignature` as *"the error code, if any, for the sign-in operation"*. Which app and which credential: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "700226" or ResultSignature == "700226" | summarize Failures = count(), LastSeen = max(TimeGenerated), Credentials = make_set(FederatedCredentialId, 5), CredentialTypes = make_set(ClientCredentialType, 5), IPs = make_set(IPAddress, 10) by AppId, ServicePrincipalName | sort by Failures desc ``` `FederatedCredentialId` is documented as *"Th identifier of an application's federated identity credential if a federated identity credential was used to sign in"* (Microsoft's typo). Whether it is populated on a refusal is not documented, so confirm on a row of your own. ## How does Conditional Access affect it? Nothing to configure here. The request fails on the token type before any policy decision matters, and a federated credential exchange for an app carries no user and no MFA step. ## How do I fix AADSTS700226? **For developers:** 1. If the workload runs on Azure, give it a **user-assigned managed identity** and present that identity's token. Set the credential's subject to the managed identity's **Object (Principal) ID**, exactly as Microsoft's page requires, and keep both objects in the same tenant. 2. If the caller is an app registration and not a managed identity, stop using the Entra issuer. Use a client secret or a certificate credential on that app, or on-behalf-of when you are acting for a signed-in user. 3. If the caller is outside Azure, use its own provider as the issuer: GitHub, Kubernetes or any OIDC provider that signs with RS256. Microsoft's restrictions page: *"Only issuers that provide tokens signed using the RS256 algorithm are supported for token exchange using workload identity federation."* **For admins:** 1. Check the federated credential's subject. It must be a user-assigned managed identity's Object (Principal) ID, not an app's service principal object ID. 2. Both objects must be in the same tenant. Microsoft: *"Both the Microsoft Entra app and managed identity must belong to the same tenant."* 3. If you did not expect an Entra-issuer credential on this app, review who added it and why, in the audit log. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Client-credentials token request with a federated identity credential, against a lab tenant; scenario: Federated credential matches). First line returned: > AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer. Lab-run rows naming this code (5; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Federated credential matches | success | 700226 | AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer. | | 2026-10-30 | Federated credential matches | success | 700226 | AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer. | | 2026-10-30 | Federated credential matches | success | 700226 | AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer. | | 2026-10-31 | Federated credential matches | success | 700226 | AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer. | | 2026-10-31 | Federated credential matches | success | 700226 | AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Configure an application to trust a managed identity](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-config-app-trust-managed-identity) 3. [Important considerations and restrictions for federated identity credentials](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-considerations) 4. [Overview of federated identity credentials (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/federatedidentitycredentials-overview) 5. [Experimenting with Entra cross-tenant application Federated Identity Credential trust to Managed Identity (GitHub)](https://github.com/arsenvlad/entra-cross-tenant-app-fic-managed-identity) 6. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS70025](https://brambrinkmeier.com/entra/aadsts/70025/), [AADSTS700211](https://brambrinkmeier.com/entra/aadsts/700211/), [AADSTS700213](https://brambrinkmeier.com/entra/aadsts/700213/), [AADSTS7002121](https://brambrinkmeier.com/entra/aadsts/7002121/), [AADSTS700212](https://brambrinkmeier.com/entra/aadsts/700212/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS700226: Only managed identity tokens work with the Entra ID issuer (fix)", https://brambrinkmeier.com/entra/aadsts/700226/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/750054/ # AADSTS750054 fix: SAML request missing from the sign-in URL Canonical: https://brambrinkmeier.com/entra/aadsts/750054/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/750054.json **Short answer:** AADSTS750054 means Microsoft Entra ID received a SAML sign-in request without a SAMLRequest or SAMLResponse in the URL query string. The app didn't use the SAML HTTP Redirect binding, or the user landed on Entra's SAML endpoint without a request, for example from a sign-on URL set for an app that only supports IdP-initiated SSO. A configuration error with low attack value. **Fix:** Admin: check that SSO is enabled in the app, that the app supports SP-initiated SSO, and that the Sign on URL in the enterprise app is right. Then run Test this application. Developer: send the AuthnRequest with HTTP Redirect binding, not HTTP POST. User: start sign-in from the app. | Field | Value | |---|---| | Code | AADSTS750054 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS750054 mean? Microsoft's description: > SAMLRequest or SAMLResponse must be present as query string parameters in HTTP request for SAML Redirect binding. To learn more, see the troubleshooting article for error [AADSTS750054](https://learn.microsoft.com/en-us/troubleshoot/azure/active-directory/error-code-aadsts750054-saml-request-not-present). The reference table gives this code no PascalCase name. In SAML single sign-on the app (the service provider) sends an authentication request to Entra. Microsoft's SAML protocol page says *"the cloud service (the service provider) uses an HTTP Redirect binding to pass an `AuthnRequest` (authentication request) element to Microsoft Entra ID"*. With that binding the request travels in the URL as a `SAMLRequest` query parameter. If Entra's SAML endpoint is reached and that parameter isn't in the URL, it returns 750054. Microsoft's troubleshooting article gives the cause: *"Microsoft Entra ID wasn't able to identify the SAML request within the URL parameters in the HTTP request. This can happen if the application is not using HTTP redirect binding when sending the SAML request to Microsoft Entra ID."* It lists three common issues: 1. Single sign-on isn't enabled on the application side. 2. The app only supports IdP-initiated SSO. Microsoft: *"[When] entering a sign-in URL for an application that only supports identity provider-initiated single sign-on can lead to a bounce back from the application without a SAML response."* 3. The sign-on URL is wrong. What users report: Auth0, set up as the SAML service provider, sends the request with HTTP POST binding when its **Protocol Binding** field is set, and gets 750054 until the field is cleared or set to HTTP-Redirect. A DocuSign SSO setup on Microsoft Q&A hit it during testing. Related SAML codes with their own page: - [76021](https://brambrinkmeier.com/entra/aadsts/76021/): the request arrived but isn't signed, and the app requires signed requests. - [75011](https://brambrinkmeier.com/entra/aadsts/75011/): the request arrived but asks for an authentication method the session doesn't match. With 750054 the request didn't arrive in the URL at all, so nothing in it was checked yet. ## Is it an attack? No. The request carries no SAML message, so there is nothing to sign anyone in with. It points at a broken SSO setup. | Pattern | Likely meaning | |---|---| | Every user of one SAML app, from the day SSO was set up | Wrong binding in the app (HTTP POST instead of HTTP Redirect), or the wrong sign-on URL. | | Users who start from the My Apps tile or a bookmark, but not from the app | The **Sign on URL** in Entra points at something that doesn't produce a SAML request, such as an app that only supports IdP-initiated SSO. Our reading of Microsoft's second cause. | | One user, once | A stale bookmark or a reloaded page on the SAML endpoint. Likely, but unconfirmed. | ## How do I find it in my logs (KQL)? Microsoft doesn't document whether 750054 is written to the sign-in logs. We assume that without a SAML request Entra may not know which app was meant, so there may be no row, or a row with little app detail. Check first: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "750054" | summarize Rows = count() by SourceTable ``` If rows exist, see which apps and protocols they belong to. Microsoft documents `AuthenticationProtocol` with the possible values *"none, oAuth2, ropc, wsFederation, saml20, deviceCode"*: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "750054" | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by AppDisplayName, AppId, AuthenticationProtocol | sort by Rows desc ``` If nothing comes back, use the correlation ID and timestamp from the user's error page. `ResultType` is a **string** column, so compare it with `"750054"`, not `750054`. ## How do I fix AADSTS750054? **For the user:** start the sign-in from the app's own address. If the error comes from a tile in My Apps, tell your IT helpdesk which tile. **For admins:** 1. In the Microsoft Entra admin center, open **Enterprise applications**, the app, then **Single sign-on**. 2. Check the **Sign on URL**. It must be a URL in the app that starts SSO and sends a SAML request. If the app only supports IdP-initiated SSO, Microsoft says a sign-on URL can cause the bounce back that ends in 750054. 3. Check with the vendor that SSO is enabled on the app side. 4. Select **Test this application**, paste the error into **Resolving Errors** and choose **Get resolution guidance**, as Microsoft's troubleshooting article describes. **For developers and app vendors:** send the `AuthnRequest` with HTTP Redirect binding, encoded into the URL as the SAML bindings specification describes, which Microsoft's article links. If your SAML library has a binding setting, set it to HTTP-Redirect. Users report that this is the fix for Auth0. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Enable single sign-on for an enterprise application (Basic SAML Configuration)](https://learn.microsoft.com/entra/identity/enterprise-apps/add-application-portal-setup-sso) 2. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 3. [Error AADSTS750054 - SAMLRequest or SAMLResponse must be present as query string parameters in HTTP request for SAML Redirect binding](https://learn.microsoft.com/en-us/troubleshoot/azure/active-directory/error-code-aadsts750054-saml-request-not-present) 4. [Single sign-on SAML protocol](https://learn.microsoft.com/en-us/entra/identity-platform/single-sign-on-saml-protocol) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 6. [Auth0 knowledge base: How to resolve the AADSTS750054 error](https://support.auth0.com/center/s/article/How-to-resolve-the-AADSTS750054-error) 7. [Microsoft Q&A: DocuSign SSO AADSTS750054](https://learn.microsoft.com/en-us/answers/questions/1404690/docusign-sso-aadsts750054-samlrequest-or-samlrespo) ## Related codes [AADSTS76021](https://brambrinkmeier.com/entra/aadsts/76021/), [AADSTS75011](https://brambrinkmeier.com/entra/aadsts/75011/), [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS750054 fix: SAML request missing from the sign-in URL", https://brambrinkmeier.com/entra/aadsts/750054/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/900023/ # AADSTS900023: Tenant identifier is not a valid tenant ID or domain (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/900023/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/900023.json **Short answer:** AADSTS900023 means the tenant part of the sign-in URL isn't a valid tenant ID or domain name at all, for example 'undefined', a stray character or an empty setting. Microsoft's error reference doesn't list it. It is a configuration error with no attack value. Put the real tenant ID (a GUID) or a verified domain in the app's settings. **Fix:** Developer: read the tenant value in the message and set the authority to a tenant GUID, a verified domain, or `organizations`/`common`/`consumers`. Fix unset variables and stray copy-paste characters. Admin: copy the tenant ID from Entra ID > Overview into the integration again. | Field | Value | |---|---| | Code | AADSTS900023 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS900023 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS900023 (checked 30 October 2026). The lab reproduced it. A token request to the tenant segment `not_a_valid~tenant` returned: > AADSTS900023: Specified tenant identifier 'not_a_valid~tenant' is neither a valid DNS name, nor a valid external domain. Every sign-in URL names a tenant: `https://login.microsoftonline.com//...`. Microsoft's MSAL configuration page says that part can be *"A GUID (the ID of your Microsoft Entra instance)"*, *"A domain name associated with your Microsoft Entra instance"*, or one of the placeholders `organizations`, `consumers` or `common`. 900023 means the value matches none of those shapes. Our reading: Entra rejects it on its form, before it looks for a tenant. Compare [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/): in the same lab run, a well-formed GUID for a tenant that doesn't exist returned 90002 ("Tenant ... not found"), not 900023. ## Reproduced in the lab On 30 October 2026 an automated lab run sent a token request to `https://login.microsoftonline.com/not_a_valid~tenant/...`. Entra returned `AADSTS900023` with the first line quoted above. The message echoes the bad value back, which is the fastest way to see what the app actually sent. That confirms the code and its wording at the token endpoint. No row for it appeared in the lab tenant's exported sign-in logs (interactive, non-interactive and service principal, exported 30 October 2026). Our reading: there is no tenant to write it to, because the request named none; see [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? No. It is a broken setting in the app, script or integration that sent the request. Users report these causes: | Value in the message | Likely meaning | |---|---| | `'undefined'` | The code built the URL from a variable that was never set. A post on the Auth0 Community forum reports it when the connection has no `domain` and `tenant_domain` set. | | A value with a stray or wrong character | A typo or copy-paste error. A user on [Microsoft Q&A](https://learn.microsoft.com/en-us/answers/a/1360543) found *"an incorrect character in the Tenant ID for the integration"*. | | The tenant field of a third-party integration | A misconfigured tenant value in the product's settings. Okta reports this for its Office 365 integration. | | Empty, a placeholder, or a whole URL | Probably a config template that was never filled in, or the wrong field pasted (unconfirmed). | Our reading: an attacker gains nothing from this error. The request never reaches a tenant, so it says nothing about yours. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 900023 is logged in. Likely no row is written in your tenant: the request named no valid tenant, so Entra can't tell whose logs it belongs in. You can check; expect nothing: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "900023" | summarize Rows = count() by SourceTable ``` Debug from the app side instead: its logs, its config, and the error message, which shows the exact tenant value it sent. ## How do I fix AADSTS900023? **For the user:** you can't fix this yourself. Report the app name and the full error message to whoever set the app up. **For developers:** 1. Read the tenant value in the message. That is what your code sent. 2. If it says `undefined` or `null`, find the variable or setting that builds the authority URL and make sure it is set in every environment. 3. Use a tenant GUID, a verified domain such as `contoso.onmicrosoft.com`, or `organizations` / `common` / `consumers`. Those are the values Microsoft documents for the authority. 4. Remove spaces, quotes and other characters that came along in a copy-paste. **For admins:** 1. Get your tenant ID. Microsoft's page on finding it says to use **Entra ID** > **Overview** > **Properties** in the Entra admin center, or `Get-AzTenant` in Azure PowerShell: ```powershell Connect-AzAccount Get-AzTenant ``` 2. Paste it into the integration's tenant field again. For Auth0, check the connection's `domain` and `tenant_domain` options; the Auth0 Community post warns that an update to `options` drops values you leave out. 3. If the integration still fails with [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), the value is now well-formed but names the wrong tenant or cloud. ## Evidence Reproduced in a lab tenant on 2026-10-30 (ROPC and other token-endpoint requests against a lab tenant; scenario: Malformed tenant identifier). First line returned: > AADSTS900023: Specified tenant identifier 'not_a_valid~tenant' is neither a valid DNS name, nor a valid external domain. Lab-run rows naming this code (8; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Malformed tenant identifier | 900023 | 900023 | AADSTS900023: Specified tenant identifier 'not_a_valid~tenant' is neither a valid DNS name, nor a valid external domain. | | 2026-10-30 | Malformed tenant identifier | 900023 | 900023 | AADSTS900023: Specified tenant identifier 'not_a_valid~tenant' is neither a valid DNS name, nor a valid external domain. | | 2026-10-30 | Malformed tenant identifier | 900023 | 900023 | AADSTS900023: Specified tenant identifier 'not_a_valid~tenant' is neither a valid DNS name, nor a valid external domain. | | 2026-10-30 | Malformed tenant identifier | 900023 | 900023 | AADSTS900023: Specified tenant identifier 'not_a_valid~tenant' is neither a valid DNS name, nor a valid external domain. | | 2026-10-30 | Malformed tenant identifier | 900023 | 900023 | AADSTS900023: Specified tenant identifier 'not_a_valid~tenant' is neither a valid DNS name, nor a valid external domain. | | 2026-10-30 | Malformed tenant identifier | 900023 | 900023 | AADSTS900023: Specified tenant identifier 'not_a_valid~tenant' is neither a valid DNS name, nor a valid external domain. | | 2026-10-31 | Malformed tenant identifier | 900023 | 900023 | AADSTS900023: Specified tenant identifier 'not_a_valid~tenant' is neither a valid DNS name, nor a valid external domain. | | 2026-10-31 | Malformed tenant identifier | 900023 | 900023 | AADSTS900023: Specified tenant identifier 'not_a_valid~tenant' is neither a valid DNS name, nor a valid external domain. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Application configuration options (MSAL)](https://learn.microsoft.com/en-us/entra/identity-platform/msal-client-application-configuration) 3. [Auth0 Community: AADSTS900023 Specified tenant identifier 'undefined' is neither a valid DNS name](https://community.auth0.com/t/azure-entra-connection-error-aadsts900023-specified-tenant-identifier-undefined-is-neither-a-valid-dns-name/122970) 4. [Okta: Microsoft Office 365 error AADSTS900023 occurs when authenticating API credentials in Okta](https://support.okta.com/help/s/article/microsoft-office-365-error-aadsts900023-occurs-when-authenticating-api-credentials-in-okta) 5. [Microsoft Q&A: Microsoft Graph API - AADSTS900023](https://learn.microsoft.com/en-us/answers/a/1360543) 6. [How to find your Microsoft Entra tenant ID](https://learn.microsoft.com/en-us/entra/fundamentals/how-to-find-tenant) 7. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS900144](https://brambrinkmeier.com/entra/aadsts/900144/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS50059](https://brambrinkmeier.com/entra/aadsts/50059/), [AADSTS90019](https://brambrinkmeier.com/entra/aadsts/90019/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS900023: Tenant identifier is not a valid tenant ID or domain (fix)", https://brambrinkmeier.com/entra/aadsts/900023/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/900144/ # AADSTS900144: Request body is missing a required parameter (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/900144/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/900144.json **Short answer:** AADSTS900144 means an app sent a request to Microsoft Entra ID without a parameter the flow requires, such as password, client_id or grant_type. Microsoft calls it a developer error. The error names the missing parameter. It has low attack value; fix the request the app builds. Look for it by app and error text in all three sign-in tables. **Fix:** Developer: read the parameter name in the error and add it to the request body, not the query string. For ROPC, send `client_id`, `grant_type`, `username` and `password` as a form-encoded `POST`. User: report the error and the parameter name to whoever runs the app. | Field | Value | |---|---| | Code | AADSTS900144 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs`, `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-25) | | Last updated | 2026-10-30 | ## What does AADSTS900144 mean? Microsoft's description: > The request body must contain the following parameter: '{name}'. Developer error - the app is attempting to sign in without the necessary or correct authentication parameters. The app sent a request to the Microsoft identity platform and left out a parameter that the flow requires. The error replaces `{name}` with the missing parameter, so the message tells you exactly what to add. Which parameters are required depends on the flow. For the resource owner password credentials (ROPC) flow, for example, Microsoft lists `client_id`, `grant_type` (*"Must be set to `password`"*), `username` and `password` as **Required**. A confidential client must also send `client_secret` or `client_assertion`. ## Reproduced in the lab On 25 October 2026 an automated lab run sent an ROPC token request to my lab tenant without the `password` parameter. Entra returned `AADSTS900144` with this first line: > AADSTS900144: The request body must contain the following parameter: 'password'. That confirms the code and its wording at the token endpoint, with `{name}` filled in as `password`. The sign-in log row was not captured, and the KQL on this page is not checked against it yet; see [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? No documented attack pattern exists for 900144. Microsoft calls it a *"Developer error"*. The request is incomplete, so no credential is checked and nothing is issued. Our reading: an attacker learns nothing from it either. | Pattern | Likely meaning | |---|---| | 900144 from one app, starting right after a release | A bug in the new version builds the request without a parameter. Configuration. | | 900144 naming `client_secret` or `client_assertion` | Our interpretation: a confidential client sent no credential, often an empty secret in the configuration or a missing environment variable. | | 900144 naming `password` or `username` from a script or tool | A script built an ROPC request with an empty value. Usually a broken automation. | | 900144 from an unknown IP, for an app ID you don't recognise | Someone is calling the token endpoint with a hand-built request. Not an attack by itself, but worth checking who owns the client. | Exclude it from failure-based attack detections. A password spray sends a password; it fails with codes such as [50126](https://brambrinkmeier.com/entra/aadsts/50126/), not 900144. ## How do I find it in my logs (KQL)? Microsoft doesn't document whether or where 900144 is logged, and the lab run above didn't capture a sign-in row, so we can't say yet whether one is written. Check all three sign-in tables: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "900144" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which app is missing which parameter. We assume `ResultDescription` carries the message with the parameter name filled in; we haven't checked that against a logged row: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "900144" | extend Parameter = extract(@"parameter: '([^']+)'", 1, ResultDescription) | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), IPs = make_set(IPAddress, 5) by AppDisplayName, AppId, Parameter | sort by Rows desc ``` New sources: apps that produced 900144 today but not in the previous 14 days. A `FirstSeen` right after a deployment points to the release that broke it: ```kusto let recent = union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "900144" | summarize Rows = count(), FirstSeen = min(TimeGenerated) by AppId, AppDisplayName; let before = union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated between (ago(15d) .. ago(1d)) | where ResultType == "900144" | distinct AppId; recent | join kind=leftanti before on AppId | sort by Rows desc ``` `AppDisplayName` doesn't exist in `AADServicePrincipalSignInLogs`; there, use `ServicePrincipalName`. `ResultType` is a **string** column, so compare it with `"900144"`, not `900144`. ## How do I fix AADSTS900144? **For the user:** you can't fix this yourself. Report the error, with the parameter name from the message, to whoever runs the app. **For developers:** 1. Read the parameter name in the error and add it to the request. 2. Check the flow's parameter table in Microsoft's documentation. For ROPC, `client_id`, `grant_type`, `username` and `password` are required, and the request is a `POST` with `Content-Type: application/x-www-form-urlencoded`. 3. Check that the parameter is in the request **body**, not the query string, as the message says. Our reading: a value that is empty or missing in your configuration ends up as no parameter at all. 4. Prefer a Microsoft Authentication Library (MSAL) over hand-built requests. Microsoft also recommends against ROPC: *"it's incompatible with multifactor authentication (MFA)."* **For admins:** 1. Use the second query to find the app and the parameter, and send both to the app's owner. 2. If the app ID is unknown, look it up in Enterprise applications or App registrations. If nobody owns it, treat it like any unknown client calling your tenant. ## Evidence Reproduced in a lab tenant on 2026-10-25 (ROPC token request against a lab tenant; scenario: Password parameter missing). First line returned: > AADSTS900144: The request body must contain the following parameter: 'password'. Lab-run rows naming this code (9; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-25 | Password parameter missing | 900144 | 900144 | AADSTS900144: The request body must contain the following parameter: 'password'. | | 2026-10-30 | Password parameter missing | 900144 | 900144 | AADSTS900144: The request body must contain the following parameter: 'password'. | | 2026-10-30 | Password parameter missing | 900144 | 900144 | AADSTS900144: The request body must contain the following parameter: 'password'. | | 2026-10-30 | Password parameter missing | 900144 | 900144 | AADSTS900144: The request body must contain the following parameter: 'password'. | | 2026-10-30 | Password parameter missing | 900144 | 900144 | AADSTS900144: The request body must contain the following parameter: 'password'. | | 2026-10-30 | Password parameter missing | 900144 | 900144 | AADSTS900144: The request body must contain the following parameter: 'password'. | | 2026-10-30 | Password parameter missing | 900144 | 900144 | AADSTS900144: The request body must contain the following parameter: 'password'. | | 2026-10-31 | Password parameter missing | 900144 | 900144 | AADSTS900144: The request body must contain the following parameter: 'password'. | | 2026-10-31 | Password parameter missing | 900144 | 900144 | AADSTS900144: The request body must contain the following parameter: 'password'. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and OAuth 2.0 Resource Owner Password Credentials](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth-ropc) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 4. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadnoninteractiveusersigninlogs) 5. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS50126](https://brambrinkmeier.com/entra/aadsts/50126/), [AADSTS90014](https://brambrinkmeier.com/entra/aadsts/90014/), [AADSTS90015](https://brambrinkmeier.com/entra/aadsts/90015/), [AADSTS900023](https://brambrinkmeier.com/entra/aadsts/900023/), [AADSTS900561](https://brambrinkmeier.com/entra/aadsts/900561/), [AADSTS901002](https://brambrinkmeier.com/entra/aadsts/901002/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS900144: Request body is missing a required parameter (fix)", https://brambrinkmeier.com/entra/aadsts/900144/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/900439/ # AADSTS900439: Azure Government app signed in on the public endpoint (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/900439/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/900439.json **Short answer:** AADSTS900439 means an app registered in the Azure Government cloud tried to sign in through a public-cloud endpoint. Microsoft's error reference doesn't list it; a Microsoft troubleshooting article does. It also covers Microsoft 365 GCC High and DoD. It is a configuration error with no attack value. Point the app at login.microsoftonline.us. **Fix:** Developer or admin: change the authority from `login-us.microsoftonline.com` to `https://login.microsoftonline.us`, and use `https://graph.microsoft.us` for Graph. Third-party product: ask the vendor for its US Government cloud setting. User: tell whoever runs the app; you can't fix this yourself. | Field | Value | |---|---| | Code | AADSTS900439 | | Microsoft name | USGClientNotSupportedOnPublicEndpoint | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS900439 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS900439 (checked 30 October 2026). Microsoft documents it in a [troubleshooting article](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-aadsts900439-usgclientnotsupportedonpublicendpoint), which names it **USGClientNotSupportedOnPublicEndpoint**: > When trying to sign in to an application registered in the Azure Government cloud using a public endpoint, the sign-in fails, and you receive the AADSTS900439 (USGClientNotSupportedOnPublicEndpoint) error. The article gives the code and name but not the full message text, and we found no user report that quotes it in full. Microsoft's cause: > Microsoft Entra authority for Azure Government has been updated from `https://login-us.microsoftonline.com` to `https://login.microsoftonline.us`. This change also applies to Microsoft 365 GCC High and Microsoft 365 DoD environments, which Microsoft Entra authority for Azure Government also services. Microsoft Entra ID enforces the correct endpoint for sign-in operations. The article adds: *"You can no longer sign in to an application registered in the Azure Government cloud using the public endpoint `https://login-us.microsoftonline.com`."* The clouds are separate. Microsoft's national clouds page: *"Each cloud instance is separate from the others and has its own environment and endpoints."* It lists `https://login.microsoftonline.us` for US Government and `https://login.microsoftonline.com` for the global service. ## Is it an attack? No. It is a configuration error in the app or its SDK settings. | Pattern | Likely meaning | |---|---| | An older app or script for a GCC High, DoD or Azure Government tenant fails | It still uses `login-us.microsoftonline.com`. | | A tool that works for commercial tenants fails for a government tenant | The tool is hard-coded to a public-cloud endpoint. Our interpretation; the article only names `login-us.microsoftonline.com`. | | A third-party product fails for your government tenant only | The vendor has no setting for the US Government cloud, or it isn't set. | ## How do I find it in my logs (KQL)? Microsoft doesn't document where 900439 is logged. Our reading: the request reaches a public-cloud endpoint, not your Azure Government tenant, so a row in your tenant's logs is unlikely. Check anyway; this is expected to return nothing: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "900439" | summarize Rows = count() by SourceTable ``` ## How do I fix AADSTS900439? **For the user:** you can't fix this yourself. Tell whoever runs the app that it uses the wrong sign-in endpoint for a US Government tenant. **For developers:** use the Azure Government endpoints. Microsoft's article lists: | Name | Azure Government endpoint | |---|---| | Portal | `https://portal.azure.us` | | Microsoft Graph API | `https://graph.microsoft.us` | | Active Directory endpoint and authority | `https://login.microsoftonline.us` | Change the authority, and the Graph base URL too if the app calls Graph. Microsoft's national clouds page: *"use the endpoints for the cloud instance where you'll deploy the application."* **For admins:** 1. Search app configs, scripts and connection settings for `login-us.microsoftonline.com` and replace it with `https://login.microsoftonline.us`. 2. For third-party products, tell the vendor your tenant is in the US Government cloud (GCC High, DoD or Azure Government) and ask for their setting for it. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Error AADSTS900439 - USGClientNotSupportedOnPublicEndpoint](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-aadsts900439-usgclientnotsupportedonpublicendpoint) 3. [National clouds (Microsoft identity platform)](https://learn.microsoft.com/en-us/entra/identity-platform/authentication-national-cloud) ## Related codes [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS900439: Azure Government app signed in on the public endpoint (fix)", https://brambrinkmeier.com/entra/aadsts/900439/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/900561/ # AADSTS900561 fix: endpoint only accepts POST, got GET Canonical: https://brambrinkmeier.com/entra/aadsts/900561/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/900561.json **Short answer:** AADSTS900561 means a Microsoft Entra endpoint that only takes POST requests received a GET. Microsoft says it can come from a developer error or from a user pressing the browser back button, and that it can be ignored. Users also report it with external MFA providers. It has low attack value. **Fix:** User: close the tab and start the sign-in again from the app, not from a bookmark or the back button. Developer: send token requests as a form-encoded POST, never from the browser address bar. Admin: if it repeats with an external MFA provider, raise it with the provider, with the correlation ID. | Field | Value | |---|---| | Code | AADSTS900561 | | Microsoft name | BadResourceRequestInvalidRequest | | Category | Graph request shape | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS900561 mean? Microsoft's description: > **BadResourceRequestInvalidRequest**: The endpoint only accepts {valid_verbs} requests. Received a {invalid_verb} request. {valid_verbs} represents a list of HTTP verbs supported by the endpoint (for example, POST), {invalid_verb} is an HTTP verb used in the current request (for example, GET). This can be due to developer error, or due to users pressing the back button in their browser, triggering a bad request. It can be ignored. Some Entra endpoints only take data in the body of a POST request. A browser that opens such a URL directly, from the address bar, a bookmark or the back button, sends a GET instead. Entra refuses it. The real message fills in the verbs, for example *"The endpoint only accepts POST, OPTIONS requests. Received a GET request."* Two Microsoft-documented places where a POST is expected: - **The token endpoint.** Microsoft's authorization code flow reference shows the code redemption as `POST /{tenant}/oauth2/v2.0/token` with a form-encoded body. Pasting a token request into a browser sends a GET. A user on Microsoft Q&A did exactly that with a device code token request and got 900561; the same request worked from curl. - **External authentication methods (EAM).** Microsoft's provider reference says the call to the provider *"is made through a `POST` request because a large list of parameters gets passed to the provider"*, and that *"the provider needs to use `POST` to send a response back to the `redirect_uri`"*. Our reading: a provider that returns to `https://login.microsoftonline.com/common/federation/externalauthprovider` with a GET, or a user who reloads that step, gets 900561. SecureAuth's knowledge base describes intermittent 900561 errors with its product set up as an EAM. ## Is it an attack? No. Microsoft says it *"can be ignored"*. It is a malformed request, and a malformed request gets nothing back. | Pattern | Likely meaning | |---|---| | A single 900561 for a user, then a normal sign-in | Back button, a reloaded page or an old tab. Benign. | | Users who open a saved login.microsoftonline.com URL | Our reading: a bookmark of a mid-sign-in URL would send a GET in the same way. Replace it with the app's own start URL. | | Every user of an external MFA provider, or many of them | The hand-off between Entra and the provider is broken. Users report this with third-party EAM providers. An integration fault, not an attack. | | One developer or script, repeatedly | A token request sent as GET, or a test pasted into a browser. Fix the client. | ## How do I find it in my logs (KQL)? Microsoft doesn't document whether 900561 is written to the sign-in logs. We assume the request often fails before Entra knows which user or app it belongs to, so there may be no row at all. SecureAuth's knowledge base says that for its EAM case the error is not recorded in the Entra sign-in or audit logs. Check whether your workspace has any: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "900561" | summarize Rows = count() by SourceTable ``` If rows exist, see which apps and clients produce them. `UserAgent` shows whether it is a browser or a script: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "900561" | summarize Rows = count(), Users = dcount(UserPrincipalName), Messages = make_set(ResultDescription, 5) by AppDisplayName, AppId, UserAgent | sort by Rows desc ``` If the union returns nothing, rely on what the user sees: the error page shows a correlation ID and a timestamp. `ResultType` is a **string** column, so compare it with `"900561"`, not `900561`. ## How do I fix AADSTS900561? **For the user:** close the tab and start again from the app's own address, not from a bookmark, the browser history or the back button. If it happens at the MFA step every time, tell your IT helpdesk. **For developers:** 1. Send token requests to `/oauth2/v2.0/token` as a POST with `Content-Type: application/x-www-form-urlencoded`, as in Microsoft's examples. A browser address bar can't do that. 2. If you build an external authentication method provider, return the response to the `redirect_uri` with a POST, as Microsoft's provider reference requires. **For admins:** 1. A one-off is noise. Microsoft says it can be ignored. 2. Users who keep hitting it from a bookmark: give them the app's start URL instead. 3. Repeated errors at the MFA step with an external authentication method: collect the correlation ID and timestamp from the error page and raise it with the provider. SecureAuth's knowledge base suggests a HAR trace and comparing the `kid` of the `id_token_hint` with your tenant's published keys; if they don't match, it advises a Microsoft support case. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow) 3. [Microsoft Entra multifactor authentication external method provider reference](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-external-method-provider) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 5. [Microsoft Q&A: Error AADSTS900561: The endpoint only accepts POST](https://learn.microsoft.com/en-us/answers/questions/938820/error-aadsts900561-the-endpoint-only-accepts-post) 6. [SecureAuth knowledge base: AADSTS900561 with SecureAuth as an external authentication method](https://support.secureauth.com/hc/en-us/articles/42577090596884) ## Related codes [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS900144](https://brambrinkmeier.com/entra/aadsts/900144/), [AADSTS90023](https://brambrinkmeier.com/entra/aadsts/90023/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS900561 fix: endpoint only accepts POST, got GET", https://brambrinkmeier.com/entra/aadsts/900561/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/901002/ # AADSTS901002 fix: resource parameter sent to v2.0 endpoint Canonical: https://brambrinkmeier.com/entra/aadsts/901002/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/901002.json **Short answer:** AADSTS901002 means an app sent the v1.0 `resource` parameter to the Microsoft identity platform (v2.0) endpoint, which only takes `scope`. It is a configuration mismatch, often in third-party products set up with v2.0 URLs. Low attack value. Replace `resource=` with `scope=/.default`, or point the app at the v1.0 endpoints it was built for. **Fix:** Developer: replace `resource=` with `scope=/.default` in requests to `/oauth2/v2.0/`. Admin of a third-party product: if the product only supports v1.0, use the v1.0 endpoint URLs, without `v2.0` in the path. User: report it to IT. | Field | Value | |---|---| | Code | AADSTS901002 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS901002 mean? Microsoft's description: > AADSTS901002: The 'resource' request parameter isn't supported. The app talks to the Microsoft identity platform endpoint (URLs containing `/oauth2/v2.0/`) but builds its request the v1.0 way, with a `resource` parameter. The two endpoints name the target API differently. Microsoft's v1.0-to-v2.0 comparison shows a v1.0 request with `&resource=https://graph.microsoft.com/` and the v2.0 equivalent with `&scope=https://graph.microsoft.com/directory.read%20...`. On v2.0, *"the **scope** parameter indicates which resource and permissions the app is requesting authorization. The desired resource is still present in the request - it's encompassed in each of the values of the scope parameter."* There is a direct translation. Microsoft's scopes reference: *"Using `scope={resource-identifier}/.default` is functionally the same as `resource={resource-identifier}` on the v1.0 endpoint."* Neither the authorization code flow nor the client credentials flow reference lists a `resource` parameter for v2.0. Not the same as [500011](https://brambrinkmeier.com/entra/aadsts/500011/). 500011 means the API you named doesn't exist in the tenant. 901002 means you named it with a parameter the endpoint doesn't accept. ## Is it an attack? No. It is a configuration mismatch between an app and the endpoint it was pointed at. The request fails and no token is issued. | Pattern | Likely meaning | |---|---| | A third-party product (BI tool, CMS plug-in, SSO module) right after it was set up | The admin entered v2.0 endpoint URLs into a product that sends `resource`. IBM documents the error for Cognos Analytics, which logs *"Call to IdP failed to get identity. Status 400"* and `invalid_request`. | | A home-built app after someone "upgraded" its URLs to v2.0 | The URLs changed but the request parameters didn't. | | A script that mixes v1.0 examples with a v2.0 token URL | Same mismatch, by hand. | Exclude it from failure-based attack detections. ## How do I find it in my logs (KQL)? Microsoft doesn't document whether or where 901002 is logged. The request is invalid, so a sign-in row may not exist. Check all three tables: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "901002" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which apps send the v1.0 parameter, and since when: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(14d) | where ResultType == "901002" | summarize Rows = count(), Users = dcount(UserPrincipalName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), IPs = make_set(IPAddress, 5) by AppDisplayName, AppId, ServicePrincipalName | sort by Rows desc ``` `AppDisplayName` is empty for rows from `AADServicePrincipalSignInLogs`, which uses `ServicePrincipalName`. `ResultType` is a **string** column, so compare it with `"901002"`, not `901002`. A `FirstSeen` that matches the day a product was configured confirms the cause. ## How do I fix AADSTS901002? **For the user:** you can't fix this yourself. Report it to IT, with the name of the app. **For developers:** 1. Remove `resource` from requests to `/oauth2/v2.0/authorize` and `/oauth2/v2.0/token`. 2. Put the API in `scope` instead. For the same access as `resource=https://graph.microsoft.com`, send `scope=https://graph.microsoft.com/.default`. For specific delegated permissions, append them to the API identifier, as in Microsoft's example `https://graph.microsoft.com/Calendars.Read`. 3. For the client credentials flow, `scope` is required and must be *"the resource identifier (application ID URI) of the resource you want, suffixed with `.default`"*. **For admins of a third-party product:** 1. Check which endpoint the product expects. If its documentation asks for a "resource" or "resource URI", it is built for v1.0. 2. Then configure the v1.0 URLs, without `v2.0` in the path. Microsoft's comparison page shows the v1.0 authorize request as `https://login.microsoftonline.com/common/oauth2/authorize`. It doesn't show the token URL; our reading is that it is `.../oauth2/token` on the same pattern. 3. If the product supports v2.0, switch its setting from resource to scope instead. Follow the vendor's guide; IBM's Cognos article is behind a login, so we couldn't read its exact steps. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Why update to Microsoft identity platform (v2.0)?](https://learn.microsoft.com/en-us/previous-versions/azure/active-directory/azuread-dev/azure-ad-endpoint-comparison) 3. [Scopes and permissions in the Microsoft identity platform](https://learn.microsoft.com/entra/identity-platform/scopes-oidc) 4. [Microsoft identity platform and the OAuth 2.0 client credentials flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-client-creds-grant-flow) 5. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 7. [Configure Cognos Analytics with Azure AD shows AADSTS901002 (IBM Support)](https://www.ibm.com/support/pages/configure-cognos-analytics-azure-ad-show-error-message-aadsts901002-resource-request-parameter-not-supported) ## Related codes [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS900144](https://brambrinkmeier.com/entra/aadsts/900144/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS90014](https://brambrinkmeier.com/entra/aadsts/90014/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS901002 fix: resource parameter sent to v2.0 endpoint", https://brambrinkmeier.com/entra/aadsts/901002/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/1002016/ # AADSTS1002016: Client uses TLS 1.0, 1.1 or 3DES (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/1002016/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/1002016.json **Short answer:** AADSTS1002016 means the client connected to Entra with TLS 1.0, TLS 1.1 or the 3DES cipher, which Entra no longer accepts. Microsoft doesn't list the code; a user reports it from an older .NET app. Microsoft retired legacy TLS for public Entra instances on 31 January 2022. It is a client configuration error with low attack value. Enable TLS 1.2. **Fix:** Developer: make the client use TLS 1.2. In .NET Framework or Windows PowerShell 5.1, set `ServicePointManager.SecurityProtocol` to `Tls12` before calling MSAL. Admin: set the .NET Framework strong-crypto registry values and restart the app. User: update the app or browser, or report it to IT. | Field | Value | |---|---| | Code | AADSTS1002016 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS1002016 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS1002016 (checked 30 October 2026). The wording below comes from user reports. A user on Microsoft Q&A posted this message from a VB.NET desktop app using MSAL.NET: > AADSTS1002016: You are using TLS version 1.0, 1.1 and/or 3DES cipher which are deprecated to improve the security posture of Azure AD. TheWindowsClub quotes the same text. The message matches Microsoft's documented TLS change. Microsoft's [TLS 1.2 guidance for Entra](https://learn.microsoft.com/troubleshoot/azure/active-directory/enable-support-tls-environment) says Entra stops supporting TLS 1.1, TLS 1.0 and the 3DES cipher suite (`TLS_RSA_WITH_3DES_EDE_CBC_SHA`). The dates on that page: | Instance | Deprecation date | Status | |---|---|---| | U.S. government | 31 March 2021 | Completed | | Public | 31 January 2022 | Completed | | Operated by 21Vianet in China | 31 January 2025 | Ongoing | The page we opened doesn't quote AADSTS1002016 itself. Our reading: this is the error Entra returns to a client that still negotiates one of the retired protocols. **In the lab, you no longer get this far.** On 30 October 2026 a lab run sent a token request to `login.microsoftonline.com` with the client pinned to TLS 1.0. The connection was reset during the TLS handshake (`ECONNRESET`), with no HTTP response and no AADSTS code. So on the public cloud today, a TLS 1.0 client fails before Entra can answer, and the symptom is a connection error in your application, not this error code. Treat AADSTS1002016 as a code from the deprecation window, or from an instance that still accepts the old protocol long enough to reply. ## Is it an attack? No. The client is old or badly configured. Microsoft's page names components that may be affected: Microsoft Entra Connect, Microsoft Graph PowerShell, application proxy connectors, PTA agents, legacy browsers and apps integrated with Entra ID. | Pattern | Likely meaning | |---|---| | A PowerShell script or .NET Framework app fails | Our reading: the .NET Framework runtime isn't using TLS 1.2. The Q&A user fixed it by forcing TLS 1.2 in code. | | A server older than Windows Server 2012 R2 fails | Microsoft says only Windows 8.1, Windows Server 2012 R2 and later support TLS 1.2 natively over WinHTTP. Earlier versions need an update and registry values. | | One old browser or device fails | Microsoft lists browsers without TLS 1.2, such as Internet Explorer 8 to 10 on Windows 7. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table AADSTS1002016 is logged in. Check all three: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "1002016" | summarize Rows = count(), LastSeen = max(TimeGenerated), IPs = make_set(IPAddress, 20) by SourceTable, AppId, UserAgent ``` Microsoft documents a second signal: *"For clients or apps that sign in over legacy TLS, Microsoft Entra ID marks the Legacy TLS field in Additional Details with True."* Its page gives a query per table. This version runs it over all three at once and adds the result code (our adaptation of Microsoft's query): ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where AuthenticationProcessingDetails has "Legacy TLS" and AuthenticationProcessingDetails has "True" | extend JsonAuthProcDetails = parse_json(AuthenticationProcessingDetails) | mv-apply JsonAuthProcDetails on ( where JsonAuthProcDetails.key startswith "Legacy TLS" | project HasLegacyTls = JsonAuthProcDetails.value ) | where HasLegacyTls == true | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, AppId, AppDisplayName, ServicePrincipalName, UserAgent, ResultType | sort by Rows desc ``` `UserAgent` often names the client, for example a PowerShell or .NET version. Our reading: if this returns nothing but the first query does, the failed rows don't carry the Legacy TLS flag. ## How do I fix AADSTS1002016? **For the user:** update the app or browser. If it's a company tool, report the error and the tool name to IT. **For developers:** make the client use TLS 1.2. - Microsoft says *".NET Framework 4.6.2 and later versions support TLS 1.2"* once the registry is set, and that 4.6 and earlier need an update. - The Q&A user fixed a .NET Framework app with one line before calling MSAL: `ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12`. - In Windows PowerShell 5.1, the same .NET setting is (our translation of that line): ```powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ``` Setting it in code fixes one process. The registry settings below fix the machine. **For admins:** on the affected Windows machine, set the values Microsoft lists. These two make .NET Framework use the OS's TLS versions and strong cryptography: ```powershell $paths = @( 'HKLM:\SOFTWARE\Microsoft\.NETFramework\v2.0.50727', 'HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319', 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727', 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319' ) foreach ($p in $paths) { if (-not (Test-Path $p)) { New-Item -Path $p -Force | Out-Null } New-ItemProperty -Path $p -Name SystemDefaultTlsVersions -Value 1 -PropertyType DWord -Force | Out-Null New-ItemProperty -Path $p -Name SchUseStrongCrypto -Value 1 -PropertyType DWord -Force | Out-Null } ``` The script is ours; the keys and values are from Microsoft's page. Restart the app or service afterwards. Microsoft also lists the SCHANNEL `TLS 1.2\Client` and `TLS 1.2\Server` keys (`Enabled` = 1, `DisabledByDefault` = 0). Windows 8.1, Windows Server 2012 R2 and later support TLS 1.2 natively over WinHTTP. Earlier versions need update 3140245. Then run the second query again to find any other clients still on legacy TLS. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. Lab-run rows naming this code (7; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Token request over TLS 1.0 | 1002016 | | no response: ECONNRESET | | 2026-10-30 | Token request over TLS 1.0 | 1002016 | | no response: ECONNRESET | | 2026-10-30 | Token request over TLS 1.0 | 1002016 | | no response: ECONNRESET | | 2026-10-30 | Token request over TLS 1.0 | 1002016 | | no response: ECONNRESET | | 2026-10-30 | Token request over TLS 1.0 | 1002016 | | no response: ECONNRESET | | 2026-10-31 | Token request over TLS 1.0 | 1002016 | | no response: ECONNRESET | | 2026-10-31 | Token request over TLS 1.0 | 1002016 | | no response: ECONNRESET | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [AADSTS1002016: You are using TLS version 1.0, 1.1 and/or 3DES cipher (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/a/1193635) 3. [Enable TLS 1.2 support in your environment (Microsoft Entra TLS 1.0 and 1.1 deprecation)](https://learn.microsoft.com/troubleshoot/azure/active-directory/enable-support-tls-environment) 4. [AADSTS1002016: You are using TLS version 1.0, 1.1 or 3DES cipher (TheWindowsClub)](https://thewindowsclub.com/aadsts1002016-you-are-using-tls-version-1-0-1-1-3des-cipher) 5. [SigninLogs table reference (Azure Monitor)](https://docs.azure.cn/en-us/azure-monitor/reference/tables/SigninLogs) ## Related codes [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS1002016: Client uses TLS 1.0, 1.1 or 3DES (fix)", https://brambrinkmeier.com/entra/aadsts/1002016/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/1003031/ # AADSTS1003031: Admin consent failed, app lists no API permissions (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/1003031/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/1003031.json **Short answer:** AADSTS1003031 means admin consent failed because the app registration's required resource access is misconfigured. Microsoft doesn't list the code. Users report it on the tenant-wide /adminconsent URL, and a Microsoft employee says the app registration had no API permissions. It is a configuration error with low attack value. Add at least one API permission to the app. **Fix:** Developer: in the app registration's API permissions, add at least one permission (for example Microsoft Graph delegated `User.Read`), and check the consent URL uses this app's client ID. Admin granting consent: stop and tell the app's developer or vendor; the fix is in their app registration. | Field | Value | |---|---| | Code | AADSTS1003031 | | Category | Consent and app permissions | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS1003031 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS1003031 (checked 30 October 2026). The wording below comes from user reports. A user on Microsoft Q&A posted this message after opening the tenant-wide admin consent URL for an external tenant: > AADSTS1003031: Misconfigured required resource access in client application registration. A second Q&A user got the same text back on the redirect URI, as `error=access_denied` with `admin_consent=True` in the query string. A third got it when an admin in another organization opened an admin consent link for a multi-tenant Teams bot. The accepted answer on the first thread comes from a Microsoft employee (Q&A moderator). It says the error occurs *"when the Tenant-Wide Admin Consent URL ... is used to add a multi-tenant application to a tenant, but the application registration in the resource tenant lacks API permissions."* And: *"If no API permissions are defined in the app registration, the consent flow fails with the error AADSTS1003031."* This is a forum answer, not a documentation page. The URL in question is the one Microsoft documents for tenant-wide admin consent: ```http https://login.microsoftonline.com/{organization}/adminconsent?client_id={client-id} ``` A volunteer moderator on the same thread points to the `requiredResourceAccess` section of the app manifest, where API permissions are declared. Our reading: the message says that list is empty or unusable for consent, which matches the employee's answer. On the second thread, an answerer wrote that the code *"doesn't exist in our public docs"* and *"does seem to match the AADSTS650056 error"*. [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/) looks like the documented, closest relative. It also covers a client that *"has not listed any permissions"*. ## Is it an attack? No. Users report it as a setup error in an app registration. The person who hits it is an admin trying to grant consent, so the attempt is deliberate and visible. | Pattern | Likely meaning | |---|---| | An admin hits it once while onboarding a new multi-tenant app | The app registration has no API permissions, as the Microsoft employee describes. | | It happens with the client ID of a backend API | Users report passing the API's client ID instead of the client app's. A Q&A volunteer moderator suggests using the frontend client ID that holds the permissions. Likely because an API registration often lists no permissions of its own (unconfirmed). | | It keeps happening after permissions were added | Possibly the consent URL still uses another app's client ID. Check the `client_id` value. | As far as we can tell, the error stops consent from being granted, so nobody gains access through it. Still review any app you didn't expect an admin to consent to. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table AADSTS1003031 is logged in. Our reading: the admin signs in interactively before consent, so the row, if any, is most likely in `SigninLogs` of the tenant where consent was attempted. Check all three tables first: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "1003031" | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable ``` Which app and which admin: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where ResultType == "1003031" | summarize Attempts = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by UserPrincipalName, AppId, AppDisplayName, HomeTenantId, ResourceTenantId | sort by LastSeen desc ``` `AppId` is the client ID to check. If `HomeTenantId` differs from your tenant, the admin was a guest. In the external-tenant case the row likely belongs to the tenant the admin consented in (unconfirmed), so the app developer's tenant may see nothing. ## How do I fix AADSTS1003031? **For the user:** if you are an admin granting consent, stop and tell the app's developer or vendor. The fix is in their app registration. If you are not an admin, pass the error and the app name to your IT team. **For developers:** 1. Open the app registration in the developer's (home) tenant. Go to **API permissions**. 2. Add at least one permission. The Microsoft employee's answer gives Microsoft Graph, delegated `User.Read`, as an example. Add the permissions the app really needs. 3. Check that the admin consent URL uses the client ID of this app. If the app calls your own API, the client app needs a permission on that API in its own registration. 4. If external tenants must use the app, the volunteer moderator's answer says to set **Supported account types** to accounts in any organizational directory, on both the client and the API registration. **For admins** (in the tenant granting consent): 1. Check the client ID in the consent URL and the permissions the app requests. Microsoft says to *"carefully review the permissions an application requests before granting consent."* 2. Tenant-wide admin consent needs a role such as Cloud Application Administrator, Application Administrator or Privileged Role Administrator. Privileged Role Administrator is needed for Microsoft Graph application permissions. 3. If the developer can't fix the registration quickly, the Microsoft employee's answer gives a workaround: create the service principal yourself. ```powershell Connect-MgGraph -Scopes Application.ReadWrite.All New-MgServicePrincipal -BodyParameter @{ AppId = "" } ``` Our reading: this only adds the app to your tenant. Any permissions still need consent once the developer has added them. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [How to setup an external tenant user to access the host tenant web app (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/2287290/how-to-setup-an-external-tenant-user-to-access-the) 3. [SSO for site not working (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/890443/sso-for-site-not-working) 4. [Cant share team app with other organizations (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/8bc571bd-1d19-4928-a517-e7e6c1eea72a/cant-share-team-app-with-other-organizations?forum=msteams-all) 5. [Grant tenant-wide admin consent to an application](https://learn.microsoft.com/entra/identity/enterprise-apps/grant-admin-consent) 6. [SigninLogs table reference (Azure Monitor)](https://docs.azure.cn/en-us/azure-monitor/reference/tables/SigninLogs) ## Related codes [AADSTS650056](https://brambrinkmeier.com/entra/aadsts/650056/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS90094](https://brambrinkmeier.com/entra/aadsts/90094/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS1003031: Admin consent failed, app lists no API permissions (fix)", https://brambrinkmeier.com/entra/aadsts/1003031/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/5000211/ # AADSTS5000211: Blocked by a tenant restrictions policy (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/5000211/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/5000211.json **Short answer:** AADSTS5000211 means a tenant restrictions v2 policy, added to the request by a corporate proxy, a managed Windows device or Global Secure Access, doesn't allow sign-in to the tenant the request was for. Microsoft's error reference doesn't list it; Microsoft's tenant restrictions v2 page shows it. It is a control doing its job. Use an allowed tenant or change the policy. **Fix:** User: use an account in an allowed tenant, or ask your IT team to allow the tenant you need. Admin who set the policy: find where it is added (proxy header, Windows device policy or Global Secure Access) and allow the external tenant in the cross-tenant access policy if the access is legitimate. | Field | Value | |---|---| | Code | AADSTS5000211 | | Category | Guests and tenants | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS5000211 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS5000211 (checked 30 October 2026). Microsoft shows it on its page [Set up tenant restrictions v2](https://learn.microsoft.com/en-us/entra/external-id/tenant-restrictions-v2), as the result of a blocked service principal sign-in with Microsoft Graph PowerShell: > Connect-MgGraph : ClientSecretCredential authentication failed: AADSTS5000211: A tenant restrictions policy added to this request by a device or network administrator does not allow access to 'tenant'. Tenant restrictions v2 (TRv2) is a policy an organization sets on which other tenants may be signed in to from its network and devices. The policy travels with the request. On a corporate proxy, Microsoft says to send this header to the Microsoft sign-in domains (`login.live.com`, `login.microsoft.com`, `login.microsoftonline.com`, `login.windows.net`): ```text sec-Restrict-Tenant-Access-Policy: : ``` `` is the tenant ID of the organization that set the policy and `` *"the object ID for your cross-tenant access policy"*. So the error doesn't come from the tenant you are signing in to. It comes from the policy of the organization whose network or device you are on. Microsoft names three ways the policy gets added: | Where | What Microsoft says | |---|---| | Corporate proxy | *"This header enforces your tenant restrictions v2 policy on all sign-ins on your network."* | | Managed Windows devices | *"Tenant restrictions are enforced upon resource access to provide data path coverage and protection against token infiltration. A corporate proxy isn't required for policy enforcement."* | | Global Secure Access | Universal tenant restrictions *"tag all traffic no matter the operating system, browser, or device form factor."* | In Microsoft's Chrome example, the browser shows a page saying internet access is blocked rather than this text. Our reading: the 5000211 string is what you see in scripts, SDKs and command-line tools. ## Is it an attack? No. The policy blocked a sign-in it was set up to block. The question is whether that sign-in was legitimate work. | Pattern | Likely meaning | |---|---| | A script or tool on the corporate network fails to reach a customer's or partner's tenant | That tenant isn't on your TRv2 allow list. The policy needs an exception, or the work happens elsewhere. | | A user tries to sign in to a personal or unknown tenant from a managed device | The policy did its job. Whether that needs a follow-up depends on what they were trying to do. | | It starts for many people on the same day | A TRv2 policy was just turned on, or the header was added to the proxy. | | It happens on the corporate network but not at home | The header is added by the proxy, not the device. | ## How do I find it in my logs (KQL)? Where the row lands depends on who you are. For service principals Microsoft is explicit: *"If a service principal sign-in is blocked by tenant restrictions v2, the sign-in log will only appear in the tenant that received the sign-in request. No sign-in log will be generated in the tenant where the tenant restrictions v2 policy is configured."* For user sign-ins Microsoft doesn't say. Our reading: the organization that set the policy may see nothing of its own blocks in its own sign-in logs. Check where 5000211 lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "5000211" | summarize Rows = count() by SourceTable ``` If you are the tenant receiving the sign-ins, for example a customer tenant that a partner's staff can't reach, see whose policy blocks them. `IsTenantRestricted` is documented as *"Indicates if a signIn is under a tenant restrictions policy or not"*, and `HomeTenantId` as *"the tenant identifier of the user initiating the sign in"*: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "5000211" or IsTenantRestricted == true | summarize Attempts = count(), Users = dcount(UserPrincipalName), Results = make_set(ResultType, 10), Apps = make_set(AppDisplayName, 10) by HomeTenantId, IPAddress | sort by Attempts desc ``` `IsTenantRestricted == true` also catches sign-ins that were under a policy and allowed, which is why `Results` is there. Not checked against real data yet. ## How do I fix AADSTS5000211? **For the user:** your organization's network or device doesn't allow sign-in to that tenant. Use an account in an allowed tenant, or ask your IT team to allow the one you need. Signing in from another network may work if the block comes from the proxy, but check your organization's rules first. **For developers and script owners:** 1. Check whether the request goes through a proxy or runs on a managed device. The error means the header or device policy was added, not that your app or secret is wrong. 2. Ask the team that owns the TRv2 policy to allow the target tenant for your app, or run the job from an environment the policy doesn't cover, if your organization allows that. **For admins of the organization that set the policy:** 1. Find where the policy is added: proxy header, Windows device policy, or Global Secure Access. The `` in the header is the object ID of your cross-tenant access policy. 2. Review the tenant restrictions settings in that cross-tenant access policy. If the access is legitimate, allow the external tenant there. Our reading of the setup page; we have not tested a policy change. 3. If you previously set up tenant restrictions v1 to block consumer sign-ins, Microsoft says *"you need to stop sending `restrict-msa` to login.live.com"* once you move to v2. **For admins of the tenant being signed in to:** you can't fix it on your side. The block is the other organization's policy. Tell them which tenant ID and app their people need. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Set up tenant restrictions v2](https://learn.microsoft.com/en-us/entra/external-id/tenant-restrictions-v2) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS53003](https://brambrinkmeier.com/entra/aadsts/53003/), [AADSTS90072](https://brambrinkmeier.com/entra/aadsts/90072/), [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS500021](https://brambrinkmeier.com/entra/aadsts/500021/), [AADSTS5000224](https://brambrinkmeier.com/entra/aadsts/5000224/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS5000211: Blocked by a tenant restrictions policy (fix)", https://brambrinkmeier.com/entra/aadsts/5000211/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/5000224/ # AADSTS5000224 fix: tenant blocked for suspected fraud Canonical: https://brambrinkmeier.com/entra/aadsts/5000224/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/5000224.json **Short answer:** AADSTS5000224 means the Microsoft Entra tenant is blocked, and Microsoft's internal name points to fraud. Nobody can sign in to it. Microsoft documents no setting an admin can change to undo it: the error text says to contact Microsoft support. If you see it for a foreign tenant in your own logs, check which tenant and app your users were reaching. **Fix:** Admin of the blocked tenant: open a case with Microsoft support. You can't lift the block yourself. If no admin can sign in, use Microsoft Support for business or your Azure support plan. User: tell your IT team. If you only have the error in the Azure portal, sign in to your own tenant directly. | Field | Value | |---|---| | Code | AADSTS5000224 | | Microsoft name | NotAllowedTenantBlockedTenantFraud | | Category | Guests and tenants | | Type | Failure | | Attack signal | Medium: worth a look in context | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-11-01 | ## What does AADSTS5000224 mean? Microsoft's description: > **NotAllowedTenantBlockedTenantFraud**: We are sorry, this resource is not available. If you are seeing this message by mistake, please contact Microsoft support. The message the user sees says only that the resource isn't available. The internal name says more: the tenant is not allowed because it was blocked, and the block is tagged as fraud. Microsoft doesn't publish the criteria, how the block is decided, or how long it lasts. Its own text gives one remedy: contact Microsoft support. In the Microsoft Q&A threads about this code, Microsoft moderators describe it as the tenant's authentication being *"temporarily disabled due to a recent security incident"*, and in one thread say it is not caused by a subscription expiring. Those are forum answers, not documentation. In one thread the product group later reported that the tenant the user named was not blocked at all, and the error came from a different tenant. Don't confuse it with [5000225](https://brambrinkmeier.com/entra/aadsts/5000225/), a tenant made inaccessible because it was **inactive**. That one has a documented reactivation process and a 20-day deadline. For 5000224, Microsoft documents neither. ## Is it an attack? Not on you, in most cases. Which tenant is blocked decides what it means: | Pattern | Likely meaning | |---|---| | Every account in your own tenant, admins included, fails with 5000224 | Microsoft has blocked your tenant. Contact Microsoft support. | | One person, in the Azure portal only, with an old demo or trial tenant | The portal opened a blocked directory. A user on Q&A traced it to the **Startup directory** set to "Last accessed", pointing at an expired demo tenant. Their own fix, not Microsoft guidance, and a Microsoft moderator in the same thread said expiry was not the cause. | | Your users, in your logs, failing for a resource or app in **another** tenant | Our interpretation: they tried to reach a tenant Microsoft flagged for fraud. Find out which tenant and app, and how the user got there (a link, a guest invitation, an app consent). | The third row is why this page rates the signal medium rather than low. Microsoft doesn't document what a fraud block covers, so the link to phishing or abuse is our reading, not a fact. ## How do I find it in my logs (KQL)? Microsoft doesn't document whether 5000224 is logged, or in which tenant. If your own tenant is blocked, you probably can't sign in to read its logs at all. For the other case, check whether your workspace has rows: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "5000224" | summarize Rows = count() by SourceTable ``` Which tenants and apps your users were trying to reach. Microsoft documents `HomeTenantId` as *"the tenant identifier of the user initiating the sign in"* and `ResourceTenantId` as *"the tenant identifier of the resource referenced in the sign in"*: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "5000224" | summarize Attempts = count(), Users = make_set(UserPrincipalName, 20), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by HomeTenantId, ResourceTenantId, AppOwnerTenantId, AppDisplayName, AppId, CrossTenantAccessType | sort by Attempts desc ``` A foreign `ResourceTenantId` or `AppOwnerTenantId` in the result is the lead. Check what else your users did with that tenant ID or app ID in the same period. Any row is worth a look; there is no baseline to set a threshold against. `ResultType` is a **string** column, so compare it with `"5000224"`, not `5000224`. ## How do I fix AADSTS5000224? **For the user:** you can't fix it. If it is your organization's tenant, tell your IT team. If you see it in the Azure portal and you have more than one directory, one user reports that signing in directly to their own tenant (`https://portal.azure.com/`) and changing the startup directory got them past it. **For admins of the blocked tenant:** 1. Microsoft documents no admin setting that lifts this block. The error text sends you to Microsoft support, and that is the only route. 2. The normal route is a support request in the Microsoft Entra admin center, as at least a **Service Support Administrator**. If any admin account can still sign in, use it. 3. Microsoft's support page also lists two other routes: a request through your Azure support plan, or [Microsoft Support for business](https://support.serviceshub.microsoft.com/supportforbusiness) if you are not an Azure customer. Microsoft says support *"is available online and by phone for Microsoft paid and trial subscriptions"*. It doesn't document a route specific to blocked tenants. 4. Have the tenant ID, the full error, the correlation ID and the timestamp from the error page ready. Microsoft moderators on Q&A asked for the tenant's onmicrosoft.com domain and the Global Administrator's UPN, sent privately. 5. Expect it to take time. One user on Q&A reported a case running for about seven weeks without a public resolution. **For admins who see it for another tenant:** you can't and shouldn't fix it. Run the second query, identify the tenant and app, and decide whether to block that app or domain in your own tenant. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Find help and get support for Microsoft Entra ID](https://learn.microsoft.com/entra/fundamentals/how-to-get-support) 3. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 4. [Microsoft Q&A: Error code AADSTS5000224](https://learn.microsoft.com/en-us/answers/questions/2247014/error-code-aadsts5000224) 5. [Microsoft Q&A: Azure portal sign-in error AADSTS5000224](https://learn.microsoft.com/en-us/answers/questions/2235851/azure-portal-sign-in-error-aadsts5000224) ## Related codes [AADSTS5000225](https://brambrinkmeier.com/entra/aadsts/5000225/), [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS5000211](https://brambrinkmeier.com/entra/aadsts/5000211/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS5000224 fix: tenant blocked for suspected fraud", https://brambrinkmeier.com/entra/aadsts/5000224/ (CC BY 4.0), last updated 2026-11-01. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/5000225/ # AADSTS5000225: Tenant blocked due to inactivity (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/5000225/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/5000225.json **Short answer:** AADSTS5000225 means Microsoft made the whole Microsoft Entra tenant inaccessible because it was inactive. Nobody can sign in to it, admins included. Microsoft's error reference doesn't list it; Microsoft's inactive-tenant page does. An admin can ask Microsoft to reactivate it within 20 days. After that the tenant is deleted and can't be recovered. **Fix:** Admin: decide now whether you need the tenant, because it is deleted after 20 days. To reactivate, call Microsoft through the support numbers on the inactive-tenant page and open only one request. User: tell an admin now if the tenant is your organization's. Developer: stop retry loops against it. | Field | Value | |---|---| | Code | AADSTS5000225 | | Category | Guests and tenants | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS5000225 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS5000225 (checked 30 October 2026). Microsoft documents it on its page [Tenant inaccessible due to inactivity](https://learn.microsoft.com/entra/fundamentals/inaccessible-tenant): > Error message `Error message: AADSTS5000225: This tenant has been blocked due to inactivity. To learn more about ...` is expected for tenants inaccessible due to inactivity. Users on Microsoft Q&A quote the full text: > AADSTS5000225: This tenant has been blocked due to inactivity. To learn more about tenant lifecycle policies, see https://aka.ms/TenantLifecycle The block is on the tenant, not on a user. Microsoft's reason: *"Configured tenants no longer in use might still generate costs for your organization. Making a tenant inaccessible due to inactivity helps reduce unnecessary expenses."* The deadline is short. Microsoft: *"Administrators can request a tenant to be reactivated within 20 days of the tenant entering an inactive state. Tenants that remain in this state for longer than 20 days are deleted."* And: *"The tenant is deleted after 20 days of being inaccessible due to inactivity and it isn't recoverable."* Microsoft's page doesn't say what counts as inactive. Moderators on Q&A marked as Microsoft External Staff write that the tenant *"has been inactive for over 200 days past the billing cycle"*. That figure is not on Microsoft's documentation page, so treat it as a support answer, not a documented rule. ## Is it an attack? No. Microsoft blocked the tenant. Nobody did it to you. | Pattern | Likely meaning | |---|---| | A test, trial or developer tenant nobody used for months | The normal case. If you still need it, act within 20 days. | | A personal Microsoft account that still belongs to a former employer's tenant | A user on Q&A reports this when trying to leave the organization so they could delete their account. Their own account isn't blocked; the old tenant is. | | An app that signs in to a customer's or partner's tenant suddenly gets this | That tenant was blocked. It is their admin's problem, not yours. | | A production tenant you use every day | Unexpected. Open a case with Microsoft straight away. | ## How do I find it in my logs (KQL)? Microsoft doesn't document where 5000225 is logged. Our reading: if your own tenant is blocked you can't sign in to read its logs, and a sign-in to someone else's blocked tenant is logged there if anywhere, not in yours. If your workspace still receives data, this check is expected to return nothing: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "5000225" | summarize Rows = count(), Apps = make_set(AppDisplayName, 10) by SourceTable ``` ## How do I fix AADSTS5000225? **For the user:** you can't fix it. If the tenant belongs to your organization, tell an admin now, because of the 20-day limit. If it belongs to a former employer or a test you no longer need, you can ignore it. A user on Q&A who wanted to leave such a tenant was advised by another user, not by Microsoft, to contact Microsoft support. **For developers and app owners:** Microsoft says to *"minimize the number of authentication requests sent to this deactivated tenant until the tenant is reactivated."* Stop retry loops against it. Don't open more than one support request; Microsoft says it contacts you once a decision is made. **For admins:** 1. Decide quickly whether you need the tenant. After 20 days it is deleted and can't be recovered. 2. To reactivate, contact Microsoft through the global support phone numbers linked from Microsoft's inactive-tenant page. Microsoft asks you to *"refrain from submitting another assistance request while your existing case is in process and until you receive a response with a decision on this case."* 3. Have the details ready. A Microsoft External Staff moderator on Q&A asked for the tenant ID, the error code, the correlation ID and timestamp of a recent failure, and a business justification. 4. If it was only a test tenant, the same moderator's advice is to create a new one instead. 5. If you don't plan to reactivate it, review Microsoft's data protection policies, which the page links to. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Tenant inaccessible due to inactivity](https://learn.microsoft.com/entra/fundamentals/inaccessible-tenant) 3. [Microsoft Q&A: "This tenant has been blocked due to inactivity."](https://learn.microsoft.com/en-us/answers/questions/2277991/this-tenant-has-been-blocked-due-to-inactivity) 4. [Microsoft Q&A: error code aadsts5000225](https://learn.microsoft.com/en-us/answers/questions/5888963/error-code-aadsts5000225) ## Related codes [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS50034](https://brambrinkmeier.com/entra/aadsts/50034/), [AADSTS5000224](https://brambrinkmeier.com/entra/aadsts/5000224/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS5000225: Tenant blocked due to inactivity (fix)", https://brambrinkmeier.com/entra/aadsts/5000225/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/5000611/ # AADSTS5000611: Key Derivation Function version 1 is invalid (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/5000611/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/5000611.json **Short answer:** AADSTS5000611 means a Windows device tried to authenticate with the retired KDFv1 algorithm, which Microsoft Entra ID now blocks because of CVE-2021-33781. Microsoft's error reference doesn't list it, but a Microsoft deprecation notice does. It hits joined and hybrid joined devices on Windows builds without the July 2021 fix. Low attack value; update the device. **Fix:** User: install all pending Windows updates, restart and sign in again; tell IT if updates won't install. Admin: find the affected devices with the second query and update them. If a device stays on the list after updating, check its Windows build; an older Windows 10 build may need a feature upgrade. | Field | Value | |---|---| | Code | AADSTS5000611 | | Category | Devices | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS5000611 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS5000611 (checked 30 October 2026). Microsoft documents it in a deprecation notice for the Key Derivation Function version 1 (KDFv1) algorithm. The notice gives the sign-in log entry as: > Sign-in error code: 5000611 > Failure reason: Symmetric Key Derivation Function version '1' is invalid. Update the device with the latest updates. Microsoft's background, from the same notice: - KDFv1 was *"used for the authentication of Microsoft Entra joined or Microsoft Entra hybrid joined devices in builds of Windows released before July 2021."* - A flaw that *"allowed unauthorized authentication"* is tracked as CVE-2021-33781. Microsoft fixed it in a Windows security update in July 2021, and *"all Windows builds released after July 2021 no longer use the KDFv1 algorithm."* - Microsoft is *"incrementally rolling out a security update that blocks the use of the KDFv1 algorithm."* *"Unpatched Windows devices won't authenticate with Microsoft Entra once the rollout of this change completes."* *"Early in the rollout retrying authentication will likely succeed."* The notice gives no enforcement dates and no KB numbers. Users quote the message with slightly different wording. On Microsoft Q&A, a user on Windows 10 who couldn't open Microsoft 365 mail or a company intranet site posted this message: > AADSTS5000611: Symmetric Key Derivation Function version 'KDFV1' is invalid. Update the device for the latest updates. The version appears as `'KDFV1'` there and as `'1'` in Microsoft's notice. Match on the code, not on the text. ## Is it an attack? No. It is an outdated Windows device failing a check that protects against a known vulnerability. The block is the fix working. | Pattern | Likely meaning | |---|---| | 5000611 from a few Windows 10 devices | Devices missing security updates since mid-2021. Update them. | | 5000611 that sometimes succeeds on retry | Microsoft says retries likely succeed early in the rollout. Expect that to stop. | | 5000611 that persists after "all updates are installed" | Users report this on Windows 10 builds that couldn't move to a newer feature release. Check the build, not just the update status. | | 5000611 only in older Office apps | Users report it in Office 2016 and Outlook 2019, and report working around it by moving to Microsoft 365 apps. User reports only; Microsoft doesn't say this. | ## How do I find it in my logs (KQL)? Microsoft says *"this error message is also present in the Microsoft Entra sign-in logs"*, but not in which table. Check where it lands: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "5000611" | summarize Rows = count() by SourceTable ``` The list of affected devices, which is what Microsoft's notice asks you to build. `DeviceDetail` is dynamic in `SigninLogs` and a string in `AADNonInteractiveUserSignInLogs`, so each leg parses it first. Property names come from the Graph `deviceDetail` resource; `operatingSystem` is documented as *"the OS name and version used in the sign-in"*: ```kusto let rows = union (SigninLogs | extend D = parse_json(tostring(DeviceDetail)) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, D), (AADNonInteractiveUserSignInLogs | extend D = parse_json(DeviceDetail) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, D); rows | where TimeGenerated > ago(30d) | where ResultType == "5000611" | extend DeviceId = tostring(D.deviceId), DeviceName = tostring(D.displayName), OS = tostring(D.operatingSystem), TrustType = tostring(D.trustType) | summarize Rows = count(), Users = make_set(UserPrincipalName, 10), Apps = make_set(AppDisplayName, 10), LastSeen = max(TimeGenerated) by DeviceId, DeviceName, OS, TrustType | sort by LastSeen desc ``` Hand the `DeviceName` list to whoever runs patching. Our reading is that a device stops appearing here once it is updated; if it keeps appearing, the update didn't take. ## How do I fix AADSTS5000611? **For the user:** install all pending Windows updates, restart, and sign in again. If Windows can't install the updates (for example, not enough disk space), tell IT. Retrying may work for a while, but Microsoft says it will stop working. **For admins:** 1. Build the device list with the second query. 2. Update those devices. Microsoft: *"All Windows devices that authenticate using Microsoft Entra must have the security patch applied or be running builds of Windows released after July 2021."* 3. If a device stays on the list after updating, check its Windows build. In Q&A 5491800, installing the latest updates for an older Windows 10 build didn't help. A volunteer moderator suggested upgrading to 22H2; the thread doesn't confirm that it worked. Microsoft doesn't name a standalone patch. 4. Microsoft also recommends looking for affected builds proactively, using the guidance in CVE-2021-33781, and setting automated update policies. 5. If only an old Office version fails on an updated device, users report working around it by moving to Microsoft 365 apps. Treat that as a user report, not a documented fix. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Deprecation of Key Derivation Function version 1 (Microsoft Entra devices)](https://learn.microsoft.com/en-us/entra/identity/devices/deprecation-key-derivation-function-version-1) 3. [Symmetric Key Derivation Function version 'KDFV1' is invalid (Microsoft Q&A 5491800)](https://learn.microsoft.com/en-us/answers/questions/5491800/symmetric-key-derivation-function-version-kdfv1-is) 4. [How to resolve AADSTS5000611 error while activating O365 (Microsoft Q&A 5522370)](https://learn.microsoft.com/en-us/answers/questions/5522370/how-to-resolve-aadsts5000611-error-while-activate) 5. [deviceDetail resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/devicedetail) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 7. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/AADNonInteractiveUserSignInLogs) ## Related codes [AADSTS50097](https://brambrinkmeier.com/entra/aadsts/50097/), [AADSTS135011](https://brambrinkmeier.com/entra/aadsts/135011/), [AADSTS700003](https://brambrinkmeier.com/entra/aadsts/700003/), [AADSTS53000](https://brambrinkmeier.com/entra/aadsts/53000/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS5000611: Key Derivation Function version 1 is invalid (fix)", https://brambrinkmeier.com/entra/aadsts/5000611/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/5002730/ # AADSTS5002730: Unsupported key for the JWT signing algorithm (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/5002730/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/5002730.json **Short answer:** AADSTS5002730 means Entra rejected a JWT because its signing algorithm doesn't fit the key. Microsoft doesn't list the code. The MSAL.NET 4.60.1 release notes tie it to certificate sign-in with SHA2 and PSS signing and an Entra bug; the fix was to upgrade MSAL.NET. Users also report it for OBO with an HS256 token. Low attack value. **Fix:** Developer: on MSAL.NET 4.60.0, upgrade to 4.60.1 or later. If you build the client assertion yourself, use `alg` PS256 with PSS padding and a `x5t#S256` header. For OBO, exchange an Entra-issued access token, not an HS256 token. Admin: nothing to change in Entra; tell the app owner. | Field | Value | |---|---| | Code | AADSTS5002730 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS5002730 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS5002730 (checked 30 October 2026). The closest listed code is AADSTS50027, `InvalidJwtToken`. Microsoft's MSAL.NET team describes it in the [4.60.1 release notes](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/releases/tag/4.60.1). The fix addressed: > an issue where attempts to acquire a token via certificate authentication resulted in a Microsoft.Identity.Client.MsalServiceException (Error code: AADSTS5002730), signaling an "Invalid JWT token. Unsupported key for the signing algorithm." This was due to a known bug in Microsoft Entra ID (Azure AD) that affects the handling of JWT tokens signed with certain algorithms, specifically SHA2 and PSS. The bug report behind it, [MSAL.NET issue 4690](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/4690), shows the full message: > AADSTS5002730: Invalid JWT token. Unsupported key for the signing algorithm. That report used a confidential client with a PEM certificate and `AcquireTokenForClient`, on MSAL.NET 4.60.0. A maintainer said a partner team's first look suggested *"an external issue (AAD)"*. The workaround in the thread was to stay on 4.59.0. So the documented trigger is a client assertion: the signed JWT an app sends instead of a client secret when it signs in with a certificate. Microsoft's certificate credentials page now says the assertion's `alg` *"Should be **PS256**"* and to *"Use PSS padding."* Our reading: the 4.60.0 failure was on the Entra side, and PS256 itself is the recommended algorithm. Microsoft doesn't say whether or when the Entra bug was fixed. A second trigger comes from a user report. A user on Microsoft Q&A got the same message in an on-behalf-of (OBO) exchange from a Teams tab app. The user believed the token they exchanged was signed with **HS256**. They said the same code got an RS256 token in another tenant. A volunteer moderator, an MVP and not Microsoft staff, answered with "I think": such a token can't be exchanged, and an Entra-issued token is needed. Our reading: here the JWT is the incoming user token, not a client assertion, and HS256 is a shared-secret algorithm that Entra doesn't accept for it. ## Is it an attack? Not on the evidence available. Both reports are apps with a signing or library problem. | Pattern | Likely meaning | |---|---| | A service or daemon fails right after a library upgrade | The MSAL.NET 4.60.0 case. Upgrade to 4.60.1 or later. | | One app fails, others with certificates work | Probably the app builds its own client assertion with an `alg` that doesn't match its key (unconfirmed). | | An OBO call fails in a Teams or custom app | The incoming token isn't an Entra-issued, RS256-signed token. Users report this. | | Your app IDs, from IPs you don't recognise | We found no report of this. Possibly someone sending hand-built assertions for your app. Check the app's credentials and sign-ins. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table AADSTS5002730 is logged in. Our reading: the certificate case is an app signing in as itself, so `AADServicePrincipalSignInLogs` is the likely table; the OBO case involves a user, so it may land in a user table. Check all three: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "5002730" | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, AppId ``` For apps signing in as themselves, see which credential was used: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "5002730" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), IPs = make_set(IPAddress, 20) by AppId, ServicePrincipalName, ClientCredentialType, ServicePrincipalCredentialThumbprint | sort by Rows desc ``` If `FirstSeen` lines up with a deployment, check which MSAL version that deployment shipped. ## How do I fix AADSTS5002730? **For developers:** 1. On MSAL.NET 4.60.0, upgrade to 4.60.1 or later. The release notes say 4.60.1 addressed this error. 2. If you build the client assertion yourself, follow Microsoft's certificate credentials page: `alg` PS256, `typ` JWT, a `x5t#S256` thumbprint header, PSS padding. 3. For OBO, exchange an Entra-issued access token for your API. Don't pass a token signed with a shared secret (HS256). The Q&A answer recommends the Teams SSO flow or MSAL to get it. **For admins:** 1. Use the second query to find the app and certificate thumbprint. Give them to the app's owner. 2. Ask the owner which MSAL version and signing settings the app uses. Nothing in Entra needs changing for the MSAL.NET case. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [MSAL.NET release 4.60.1 (GitHub)](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/releases/tag/4.60.1) 3. [[Bug] Using the SHA2 feature will cause the following errors (MSAL.NET issue 4690)](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/4690) 4. [Invalid JWT token. Unsupported key for the signing algorithm (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/a/2062046) 5. [Microsoft identity platform application authentication certificate credentials](https://learn.microsoft.com/entra/identity-platform/certificate-credentials) 6. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://docs.azure.cn/en-us/azure-monitor/reference/tables/AADServicePrincipalSignInLogs) ## Related codes [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS7000222](https://brambrinkmeier.com/entra/aadsts/7000222/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS5002730: Unsupported key for the JWT signing algorithm (fix)", https://brambrinkmeier.com/entra/aadsts/5002730/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/7000014/ # AADSTS7000014: Device code value isn't valid (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/7000014/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/7000014.json **Short answer:** AADSTS7000014 means a device code token request carried a device_code value that Entra doesn't accept. In the lab it came back for a device_code that was never issued. Microsoft doesn't document the code; most likely the app sent a wrong, cut-off or made-up value, not an expired one (that is 70020, per user reports). It has low attack value. Fix how the app stores and sends the code. **Fix:** User: start the sign-in again so the app gets a fresh code; if it fails again, report the tool and version to its maintainer. Developer: poll `/token` with the exact `device_code` string from `/devicecode` (not the `user_code`), using the same `client_id` and tenant endpoint for both calls. | Field | Value | |---|---| | Code | AADSTS7000014 | | Category | Tokens and sessions | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS7000014 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS7000014 (checked 30 October 2026). I found no other Microsoft page that documents it either. My lab tenant returned this message for a device code token request whose `device_code` value had never been issued: > AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. How the device code flow works, from Microsoft's device code page: the app first calls `/devicecode` and gets back a `device_code`, *"A long string used to verify the session between the client and the authorization server."* The app then polls `/token` with `grant_type=urn:ietf:params:oauth:grant-type:device_code`, the same `client_id` (*"Must match the `client_id` used in the initial request"*) and that `device_code`. 7000014 is a rejection of the `device_code` value in that second step. Microsoft's page lists the protocol errors an app can get while polling. One of them fits this case: > `bad_verification_code`: The `device_code` sent to the `/token` endpoint wasn't recognized. Verify that the client is sending the correct `device_code` in the request. Our reading: 7000014 is the AADSTS code behind an unrecognised `device_code`. The lab run recorded only the message line, not the `error` field, so which protocol error comes with it is not confirmed. Two sibling codes have nearly the same wording. Neither is in Microsoft's reference either, and the wording below comes from user reports: | Code | Message as users posted it | Meaning | |---|---|---| | 70020 | *"The provided value for the input parameter 'device_code' is not valid. This device code has expired."* ([azure-cli issue 22251](https://github.com/Azure/azure-cli/issues/22251)) | The code was real but its time ran out. | | 90132 | *"The provided value for the input parameter 'device_code' is not valid. Device codes supporting the personal Microsoft Account sign-in audience can only be used for v2 common or consumers tenants."* ([Microsoft Q&A 929217](https://learn.microsoft.com/en-us/answers/questions/929217/oauth2-error-aadsts90132-device-code-is-not-valid)) | A personal account was used with a tenant-specific endpoint. | 7000014 carries no such second sentence. It looks like the general "this value isn't one we recognise" case. ## Reproduced in the lab On 30 October 2026 an automated lab run sent a device code token request to my lab tenant with a `device_code` that the tenant had never issued. Entra returned `AADSTS7000014` with this first line: > AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. That confirms the code and its wording at the token endpoint. Note what the run expected: 70020, 70000 or 9002313. It got none of those. No row for it appeared in the lab tenant's exported sign-in logs (interactive, non-interactive and service principal, exported 30 October 2026). Likely a device code that was never issued is rejected before any sign-in is recorded, but that is unconfirmed. The KQL on this page returns nothing on the lab rows, as expected. ## Is it an attack? Usually not. It points to an app that sends a broken `device_code`. | Pattern | Likely meaning | |---|---| | A CLI, script or tool fails right after it shows the "enter the code" message | The app stores or sends the `device_code` wrongly: cut off, double-encoded, or from a different request. Likely, but unconfirmed. | | A home-grown device code script that never worked | The script polls with the `user_code` (the short code the user types) instead of the `device_code`. A guess; not tested. | | Failures after a long wait | Expect 70020 (expired) rather than 7000014, based on user reports of 70020. | | Polling with a different `client_id` or tenant than the `/devicecode` call | Microsoft requires the same `client_id`. Which code this returns is untested. | Device code phishing is a real attack: Microsoft's Conditional Access page calls the flow *"a high-risk authentication method that can be part of a phishing attack."* Our reading is that 7000014 is not a sign of it. In that attack the attacker requests a real code and polls with it, so their requests carry a valid `device_code`. A burst of 7000014 from one IP is more likely a broken tool than a phishing kit. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 7000014 is logged in. The request likely names a client and a tenant but no user, because no user ever approved a code that was never issued. A row may not exist at all. Check anyway: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType in ("7000014", "70020", "90132") | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, ResultType, AppId ``` More useful in practice: see which apps use the device code flow in your tenant and how they fare. `AuthenticationProtocol` lists `deviceCode` among its documented values: ```kusto SigninLogs | where TimeGenerated > ago(30d) | where AuthenticationProtocol == "deviceCode" | summarize Rows = count(), Users = dcount(UserPrincipalName), Failures = countif(ResultType != "0") by AppDisplayName, AppId | sort by Rows desc ``` An app that shows up here and that you don't expect is worth a look whatever its error code. ## How does Conditional Access affect it? - Microsoft *"recommends blocking device code flow wherever possible"* with a Conditional Access authentication flows policy. - Our reading: 7000014 is not that block. The value is rejected before any user is known, so there is nothing for a policy to evaluate. A user blocked by such a policy gets a Conditional Access failure on the sign-in, which you investigate on the sign-in's **Conditional Access** tab, as Microsoft's page describes. ## How do I fix AADSTS7000014? **For the user:** start the sign-in again so the app gets a fresh code. If it fails again straight away, report the tool and its version to whoever maintains it. **For developers:** 1. Poll `/token` with the exact `device_code` string from the `/devicecode` response. Don't trim, re-encode or truncate it; it is long. 2. Send the `device_code`, not the `user_code`. 3. Use the same `client_id` and the same tenant endpoint for both calls. 4. Handle the documented polling errors: repeat on `authorization_pending` after `interval` seconds; stop on `authorization_declined`, `bad_verification_code` and `expired_token`. 5. Prefer a library (MSAL) over hand-written polling. **For admins:** 1. Find the app with the first query, then ask its owner which tool and version it is. 2. If nobody should use device code flow, block it with a Conditional Access authentication flows policy. That stops the flow for real attackers too. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Device code token request against a lab tenant; scenario: Device code that was never issued). First line returned: > AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. Lab-run rows naming this code (8; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-31 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-31 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and the OAuth 2.0 device authorization grant flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-device-code) 3. [Conditional Access: Authentication flows](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-authentication-flows) 4. [Azure/azure-cli issue 22251 (AADSTS70020 with az login --use-device-code)](https://github.com/Azure/azure-cli/issues/22251) 5. [Microsoft Q&A: OAuth2 Error AADSTS90132: Device Code is not valid](https://learn.microsoft.com/en-us/answers/questions/929217/oauth2-error-aadsts90132-device-code-is-not-valid) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS70016](https://brambrinkmeier.com/entra/aadsts/70016/), [AADSTS90023](https://brambrinkmeier.com/entra/aadsts/90023/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS7000014: Device code value isn't valid (fix)", https://brambrinkmeier.com/entra/aadsts/7000014/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/7000110/ # AADSTS7000110: Code or refresh token used by a different app (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/7000110/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/7000110.json **Short answer:** AADSTS7000110 means an authorization code or refresh token was redeemed with a client ID other than the one it was issued to. Microsoft's error reference doesn't list it, but a Microsoft troubleshooting article does. Usually a config mix-up between two app registrations. Low attack value, but check unfamiliar IPs. Use the same client ID. **Fix:** Developer: redeem the authorization code or refresh token with the same `client_id` that requested it. Read the client ID from one setting for both requests, keep refresh tokens per app, and check the secret or certificate belongs to that same app. User: sign out and sign in again. | Field | Value | |---|---| | Code | AADSTS7000110 | | Category | Tokens and sessions | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS7000110 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS7000110 (checked 30 October 2026). Microsoft documents it in a troubleshooting article. The message: > Request is ambiguous, multiple application identifiers found. The client ID used to obtain the grant (e.g. refresh token or authorization code) might not match the client ID passed in this request or client credential. Microsoft's cause: the application tried to > - Redeem an OAuth2 authorization code to get an access token or a refresh token that has the wrong application ID (`client_id` parameter). > - Use a refresh token that was initially issued to the application ID of a different caller. An authorization code or refresh token belongs to the app that requested it. If the token request names another app, Entra sees two app IDs and refuses. The "client credential" part of the message suggests a third variant. Our reading: a confidential client whose secret or certificate belongs to a different app registration than the `client_id`. Microsoft's article doesn't list that case. ## Is it an attack? Usually not. It is a config mix-up. | Pattern | Likely meaning | |---|---| | Fails right after a code is returned to the app | The authorize request and the token request use different client IDs. Common when an app has separate dev and prod registrations. | | A refresh token stored by one app is reused by another | Probably two apps share a token cache or a database table (unconfirmed). | | Fails after an app registration was replaced | Stored refresh tokens still belong to the old app ID. Users have to sign in again. | | Refresh tokens for your users presented from IPs and user agents your apps don't use | Our interpretation: someone may be replaying a token captured from one app under another client ID. Check the IPs before dismissing it. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 7000110 is logged in. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "7000110" | summarize Rows = count() by SourceTable ``` Which apps, and from where. Many users on one app is a config bug. One user from an unfamiliar IP is worth a closer look: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "7000110" | summarize Rows = count(), Users = dcount(UserPrincipalName), IPs = make_set(IPAddress, 10), UserAgents = make_set(UserAgent, 5), FirstSeen = min(TimeGenerated) by AppDisplayName, AppId | sort by Users asc ``` Our reading: the `AppId` in the row is probably the client ID that was sent in the token request, not the one the token was issued to. That isn't documented. Non-interactive rows are aggregated, so counts are not request counts. ## How do I fix AADSTS7000110? **For the user:** sign out of the app and sign in again. If it keeps happening, report it to the app's owner. **For developers:** 1. Microsoft's fix: *"Use an OAuth2 authorization code or a refresh token that's from the same application ID (`client_id` parameter)."* 2. Check that the authorize request and the token request read the client ID from the same setting. Look for a dev client ID in one place and a prod one in another. 3. Keep refresh tokens per app. Don't share a token cache between two app registrations. 4. For a confidential client, check that the secret or certificate belongs to the same app registration as the `client_id`. This step comes from the message's "client credential" wording, which Microsoft doesn't explain. 5. After replacing an app registration, clear the stored refresh tokens and send users through sign-in. Microsoft's refresh token page says apps should handle revoked tokens *"by redirecting the user to an interactive sign-in prompt"*. **For admins:** 1. Find the app in the second query and give the developer its `AppId`, plus the app ID they expected. 2. If the rows come from IPs or user agents that none of your apps use, treat it like a suspicious token use. Look at the same user's successful non-interactive sign-ins from those IPs. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Error AADSTS7000110: Request is ambiguous, multiple application identifiers found](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts7000110-request-is-ambiguous) 3. [Refresh tokens in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS70008](https://brambrinkmeier.com/entra/aadsts/70008/), [AADSTS700082](https://brambrinkmeier.com/entra/aadsts/700082/), [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS7000110: Code or refresh token used by a different app (fix)", https://brambrinkmeier.com/entra/aadsts/7000110/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/7000112/ # AADSTS7000112: The application is disabled (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/7000112/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/7000112.json **Short answer:** AADSTS7000112 means the app's service principal is disabled in the tenant, so Microsoft Entra ID won't issue tokens for it. Often an admin did it on purpose, for example to cut off a suspicious app. If it hits a Microsoft app such as Exchange Online, sign-ins break tenant-wide. Find who disabled it in the audit log and re-enable it only if that was a mistake. **Fix:** Admin: first find who disabled the app and why in the audit log; leave it disabled if that was during an incident. If it was a mistake, set Enterprise applications > the app > Properties > Enabled for users to sign-in? to Yes. User: tell your IT team which app showed the error. | Field | Value | |---|---| | Code | AADSTS7000112 | | Microsoft name | UnauthorizedClientApplicationDisabled | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS7000112 mean? Microsoft's description: > **UnauthorizedClientApplicationDisabled**: The application is disabled. The app has a service principal (an enterprise application) in the tenant, and that service principal is switched off. In the Entra admin center this is the **Enabled for users to sign-in?** property. Microsoft describes what **No** does: > If this option is set to No, then no users are able to sign in to the application, even if they're assigned to it. Tokens aren't issued for the application. This setting not only prevents users from signing in but also restricts service principals from accessing the application using application permissions. In Microsoft Graph the same switch is the service principal's `accountEnabled` property: *"If set to `false`, then no users are able to sign in to this app, even if they're assigned to it."* Our reading is that 7000112 is what a client sees when it hits that switch. Microsoft's description doesn't say so in those words. The error message usually names the app. Microsoft's Exchange Online troubleshooting article shows this example: *"AADSTS7000112: Application '00000002-0000-0ff1-ce00-000000000000'(Office 365 Exchange Online) is disabled."* ### Disabled by Microsoft An app can also be disabled from Microsoft's side. Graph has a separate property, `disabledByMicrosoftStatus`, which *"Specifies whether Microsoft has disabled the registered application"*, with the value `DisabledDueToViolationOfServicesAgreement` for *"suspicious, abusive, or malicious activity, or a violation of the Microsoft Services Agreement"*. That property sits on the app registration, in the publisher's tenant. Whether a Microsoft-disabled app returns 7000112 or a different code in your tenant isn't documented. ## Reproduced in the lab On 30 October 2026 an automated lab run registered an app, created its service principal, set `accountEnabled` to `false` on that service principal, and then signed a test user in through it. Entra returned `AADSTS7000112`: > AADSTS7000112: Application ''() is disabled. That confirms the cause directly: the **service principal**, the enterprise application object in your tenant, is the thing that is disabled. The app registration itself was untouched and still existed. The message names the application ID and the display name, so you can go straight to Enterprise applications and look at that object's **Enabled for users to sign-in?** setting. The sign-in log row isn't captured yet; see [how pages are checked](https://brambrinkmeier.com/methodology/). In the lab tenant's sign-in logs the row appears under **User sign-ins (interactive)**, Status **Failure**, Conditional Access **Not Applied**. The **Application** column shows the disabled app's own display name, not the sign-in client, so the row points straight at the application you need to re-enable. ## Is it an attack? The error itself is not. It is a block working. What matters is who disabled the app and why. | Pattern | Likely meaning | |---|---| | 7000112 for an app an admin disabled during an incident | Working as intended. The app is cut off. | | 7000112 for a suspicious app after you disabled it, from IPs you don't own | Possibly the app's operator, or tooling using its tokens, is still trying (unconfirmed). Each row gives you an IP and a time. Worth recording, not worth re-enabling. | | 7000112 for a Microsoft first-party app (Exchange Online, Teams, SharePoint) | Someone disabled a Microsoft service principal in your tenant. Microsoft's Exchange Online article shows this breaks Microsoft 365 sign-in with *"Sorry, but we're having trouble signing you in."* Check the audit log for who did it. | | 7000112 for a line-of-business app nobody remembers disabling | A clean-up job, a script, or an admin who thought the app was unused. Check the audit log before re-enabling. | A disabled Microsoft first-party service principal is worth a second look. Our reading, not a Microsoft statement: disabling Exchange Online or another core service principal is a quick way to cause a tenant-wide outage, so if nobody on your team did it on purpose, treat the account that did as suspect until you know. If you disabled an app as part of a consent phishing response, see the [consent phishing investigation guide](https://brambrinkmeier.com/guides/investigate-consent-phishing-entra-id/), which treats 7000112 as one of the codes to watch afterwards. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 7000112 lands in. A disabled app blocks both users and app-only access, so it can appear in all three. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "7000112" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which disabled apps are still being used, by how many users, and from where: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "7000112" | summarize Rows = count(), Users = dcount(UserPrincipalName), IPs = dcount(IPAddress), SampleIPs = make_set(IPAddress, 10), Resources = make_set(ResourceDisplayName, 5), FirstSeen = min(TimeGenerated) by AppId, AppDisplayName = coalesce(AppDisplayName, ServicePrincipalName) | sort by Users desc ``` Who changed a service principal, and when. Microsoft's audit log reference lists **Update service principal** in the ApplicationManagement category. Disabling an enterprise app is likely logged as that activity; Microsoft doesn't say so: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where Category == "ApplicationManagement" | where OperationName == "Update service principal" | mv-expand Target = TargetResources | mv-expand Prop = Target.modifiedProperties | where tostring(Prop.displayName) == "AccountEnabled" | project TimeGenerated, App = tostring(Target.displayName), ServicePrincipalId = tostring(Target.id), OldValue = tostring(Prop.oldValue), NewValue = tostring(Prop.newValue), ByUser = tostring(InitiatedBy.user.userPrincipalName), ByApp = tostring(InitiatedBy.app.displayName) | sort by TimeGenerated desc ``` The audit activity name comes from Microsoft's audit log reference. The modified property name `AccountEnabled` is our assumption based on the Graph property, not checked against Microsoft documentation. If the query returns nothing, drop the `AccountEnabled` line and read the `modifiedProperties` of the rows yourself. Non-interactive and service principal sign-in rows are aggregated, so row counts there are not request counts. `ResultType` is a **string** column, so compare it with `"7000112"`. ## How does Conditional Access affect it? - 7000112 is not a Conditional Access block. A disabled app gets no tokens at all, whatever your policies say. - Don't confuse it with [53003](https://brambrinkmeier.com/entra/aadsts/53003/), which is a Conditional Access block. The fix and the owner are different. ## How do I fix AADSTS7000112? **For the user:** you can't fix this yourself. The app is turned off in your organisation. Tell your IT team which app showed the error. **For developers:** if your app is multi-tenant and a customer gets 7000112, the customer's admin disabled your app's service principal in their tenant. You can't re-enable it from your side. Ask them to. **For admins:** 1. Find out who disabled it and why with the audit log query, before changing anything. If it was disabled during an incident, leave it disabled. 2. If it was a mistake: in **Enterprise applications** > the app > **Properties**, set **Enabled for users to sign-in?** to **Yes**. In Microsoft Graph, set `accountEnabled` to `true` on the service principal. 3. For Exchange Online, Microsoft's article gives the steps with the old MSOnline module (`Set-MsolServicePrincipal -AccountEnabled $true` on app ID `00000002-0000-0ff1-ce00-000000000000`). That article notes the MSOnline and Azure AD modules are deprecated and points to Microsoft Graph PowerShell instead. 4. If the account that disabled a Microsoft first-party app can't explain it, investigate that account like any other suspicious admin action. 5. If you want to block an app permanently, disabling is fine. Remove it later once nothing legitimate depends on it. After removal the code a client gets will probably change, to [700016](https://brambrinkmeier.com/entra/aadsts/700016/) or 700011; which one isn't documented. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Password-grant (ROPC) token request against a lab tenant; scenario: Application disabled for sign-in). First line returned: > AADSTS7000112: Application ''() is disabled. Sign-in log row read: 2026-10-31. Lab-run rows naming this code (4; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Application disabled for sign-in | 7000112 | 7000112 | AADSTS7000112: Application '{app-id}'(lab-disabled-sp-41139925607) is disabled. | | 2026-10-30 | Application disabled for sign-in | 7000112 | 7000112 | AADSTS7000112: Application '{app-id}'(lab-disabled-sp-41143330001) is disabled. | | 2026-10-31 | Application disabled for sign-in | 7000112 | 7000112 | AADSTS7000112: Application '{app-id}'(lab-disabled-sp-41146039117) is disabled. | | 2026-10-31 | Application disabled for sign-in | 7000112 | 7000112 | AADSTS7000112: Application '{app-id}'(lab-disabled-sp-41150019626) is disabled. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Properties of an enterprise application](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/application-properties) 3. [servicePrincipal resource type (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/serviceprincipal) 4. ["Sorry, but we're having trouble signing you in" error when signing in to Microsoft 365](https://learn.microsoft.com/en-us/microsoft-365/troubleshoot/sign-in/exchange-online-application-service-principal-disabled) 5. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) ## Related codes [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS50001](https://brambrinkmeier.com/entra/aadsts/50001/), [AADSTS500014](https://brambrinkmeier.com/entra/aadsts/500014/), [AADSTS501051](https://brambrinkmeier.com/entra/aadsts/501051/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS7000112: The application is disabled (fix)", https://brambrinkmeier.com/entra/aadsts/7000112/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/7000215/ # AADSTS7000215: Invalid client secret is provided Canonical: https://brambrinkmeier.com/entra/aadsts/7000215/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/7000215.json **Short answer:** AADSTS7000215 means an app or service principal sent a client secret that Microsoft Entra ID didn't accept. Usually it is a developer or rotation mistake. The security signal is repeated failures for one app ID from an IP you don't own, which suggests someone trying a leaked or old secret. Hunt it in AADServicePrincipalSignInLogs. **Fix:** Developer: send the current secret for the right app registration and tenant. Admin: after a rotation, find every IP still failing for the app and update those systems. If failures come from an IP you don't own, create a new credential and remove the old secrets from the app registration. | Field | Value | |---|---| | Code | AADSTS7000215 | | Microsoft name | Invalid client secret | | Category | App configuration | | Type | Failure | | Attack signal | Medium: worth a look in context | | MITRE ATT&CK | [T1078.004](https://attack.mitre.org/techniques/T1078/004/) Valid Accounts: Cloud Accounts | | Where to look | `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS7000215 mean? Microsoft's description: > Invalid client secret is provided. Developer error - the app is attempting to sign in without the necessary or correct authentication parameters. The reference table gives this code no PascalCase name. Two siblings help you tell the cases apart: - **[7000222](https://brambrinkmeier.com/entra/aadsts/7000222/) InvalidClientSecretExpiredKeysProvided**: *"The provided client secret keys are expired. Create new keys for your app, or consider using certificate credentials for added security"* - **7000218**: *"The request body must contain the following parameter: 'client_assertion' or 'client_secret'."* So 7000222 means the secret was right but expired, 7000218 means no secret or assertion was sent at all, and 7000215 means a secret was sent and it was wrong. ## Reproduced in the lab On 30 October 2026 an automated lab run created an app registration with a client secret, then sent a client-credentials request with a made-up secret. Entra returned `AADSTS7000215`: > AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app ''. A control request in the same run, with the real secret, returned a token. So this code means the secret itself is wrong, not that the app or the tenant is misconfigured. The sign-in log row isn't captured yet; see [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? Usually not. Microsoft labels it a developer error, and most 7000215 comes from a typo in configuration or a system that still holds a secret you rotated. The security reading depends on where the requests come from. | Pattern | Likely meaning | |---|---| | 7000215 for one app from your own servers or build agents, starting right after a secret rotation | A system still holding the old secret. Benign, but it tells you exactly which systems to update. | | 7000215 for one app from an IP you don't own and have never seen succeed for that app | Someone trying a secret for your app from outside. A leaked or old secret is the likely source. Investigate. | | 7000215 followed by a success (`ResultType` `"0"`) for the same app from the same unknown IP | The attacker found a working secret. Treat the app as compromised. | | 7000215 spread across many app IDs from one IP | Someone testing a set of credentials against your tenant. Investigate the source. | ## How do I find it in my logs (KQL)? Failures by app and source IP: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "7000215" | summarize Attempts = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), KeyIds = make_set(ServicePrincipalCredentialKeyId, 10) by AppId, ServicePrincipalName, IPAddress | sort by Attempts desc ``` Failures from IPs that never had a success for the same app in the last 30 days: ```kusto let knownAppIPs = AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "0" | distinct AppId, IPAddress; AADServicePrincipalSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "7000215" | join kind=leftanti knownAppIPs on AppId, IPAddress | summarize Attempts = count(), LastSeen = max(TimeGenerated) by AppId, ServicePrincipalName, IPAddress | sort by Attempts desc ``` Any IP from that list that later succeeds for the same app: ```kusto let failedFrom = AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "7000215" | summarize FirstFail = min(TimeGenerated) by AppId, IPAddress; AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "0" | join kind=inner failedFrom on AppId, IPAddress | where TimeGenerated > FirstFail | project TimeGenerated, AppId, ServicePrincipalName, IPAddress, ServicePrincipalCredentialKeyId, FirstFail | sort by TimeGenerated asc ``` Check two things in your own workspace before relying on these queries: - The Azure Monitor reference for `AADServicePrincipalSignInLogs` describes `ResultType` as *"Success or Failure"*, while the user sign-in tables document it as the numeric error code as a string. Look at a few failed rows and confirm they carry `"7000215"` and that successes carry `"0"`. If they don't, filter on `ResultSignature` (*"Contains the error code, if any, for the sign-in operation"*) instead. - Whether `ServicePrincipalCredentialKeyId` is filled in on a **failed** secret isn't documented. A wrong secret may not match any key, so the column may be empty. On successes it tells you which credential was used. ## How does Conditional Access affect it? - A service principal using a client secret has no MFA step. - 7000215 is a failed credential check. For user sign-ins, Conditional Access only evaluates after the first factor succeeds; the same logic suggests no policy was evaluated here. That is reasoning from the user case, not a documented statement for service principals. - So the controls that matter are on the credential itself: who can read it, where it is stored, and whether it is a secret at all. ## How do I fix AADSTS7000215? **For developers:** check that the app sends the current secret for the right app registration and tenant. If the secret expired, you get [7000222](https://brambrinkmeier.com/entra/aadsts/7000222/), not 7000215. **For admins:** 1. After a rotation, use the first query to list every IP still failing for that app, and update those systems. 2. If failures come from an IP you don't own, treat the app's existing secrets as exposed: create a new credential, remove the old ones from the app registration, and update your own systems. 3. If the third query returns a row, the app was used by someone else. Review what the app's permissions allow and what it accessed after that time. 4. Follow Microsoft's own hint in the 7000222 message and *"consider using certificate credentials for added security"*. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Client-credentials token request against a lab tenant; scenario: Wrong client secret). First line returned: > AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app ''. Lab-run rows naming this code (7; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Wrong client secret | 7000215 | 7000215 | AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret ad | | 2026-10-30 | Wrong client secret | 7000215 | 7000215 | AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret ad | | 2026-10-30 | Wrong client secret | 7000215 | 7000215 | AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret ad | | 2026-10-31 | Device code redeemed with a different client ID | 70016 / 7000215 / 70002 | 90023 | AADSTS90023: ClientId passed in the request doesn't match the one in cache | | 2026-10-31 | Wrong client secret | 7000215 | 7000215 | AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret ad | | 2026-10-31 | Device code redeemed with a different client ID | 70016 / 7000215 / 70002 | 90023 | AADSTS90023: ClientId passed in the request doesn't match the one in cache | | 2026-10-31 | Wrong client secret | 7000215 | 7000215 | AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret ad | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS7000222](https://brambrinkmeier.com/entra/aadsts/7000222/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS70002](https://brambrinkmeier.com/entra/aadsts/70002/), [AADSTS700024](https://brambrinkmeier.com/entra/aadsts/700024/), [AADSTS900144](https://brambrinkmeier.com/entra/aadsts/900144/), [AADSTS5002730](https://brambrinkmeier.com/entra/aadsts/5002730/), [AADSTS7000110](https://brambrinkmeier.com/entra/aadsts/7000110/), [AADSTS7000112](https://brambrinkmeier.com/entra/aadsts/7000112/), [AADSTS7000216](https://brambrinkmeier.com/entra/aadsts/7000216/), [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS9002326](https://brambrinkmeier.com/entra/aadsts/9002326/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS7000215: Invalid client secret is provided", https://brambrinkmeier.com/entra/aadsts/7000215/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/7000216/ # AADSTS7000216: No client credential in a client_credentials request (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/7000216/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/7000216.json **Short answer:** AADSTS7000216 means a token request used grant_type=client_credentials but carried no client_secret, no client_assertion and no request parameter, so Entra had nothing to authenticate the app with. Microsoft's error reference doesn't list it. It is a developer error with low attack value. Send the app's secret or a signed client assertion. **Fix:** Developer: add the credential to the POST body. With a secret, send `client_secret`. With a certificate or federated credential, send `client_assertion` plus `client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer`. | Field | Value | |---|---| | Code | AADSTS7000216 | | Category | App configuration | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS7000216 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS7000216 (checked 30 October 2026). We found no other Microsoft page that names it. The wording below is from a lab run: > AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. A client-credentials request is an app signing in as itself, so the only thing proving who it is, is the credential in the POST body. 7000216 means there wasn't one. Microsoft's client credentials flow page gives three shapes of that request, and each needs a credential: | Credential | Parameters Microsoft lists | |---|---| | Shared secret | `client_id`, `scope`, `client_secret`, `grant_type=client_credentials` | | Certificate | `client_id`, `scope`, `client_assertion_type`, `client_assertion`, `grant_type=client_credentials` | | Federated credential | `client_assertion` from an external identity provider | Microsoft's own note on the certificate form: *"The parameters for the certificate-based request differ in only one way from the shared secret-based request: the `client_secret` parameter is replaced by the `client_assertion_type` and `client_assertion` parameters."* `client_assertion_type` has one accepted value, `urn:ietf:params:oauth:client-assertion-type:jwt-bearer`. The error message also names a third option, `request`. That parameter is not in any of the three tables on Microsoft's client credentials page, so we can't tell you from Microsoft's documentation what Entra accepts in it. Our reading, from the name and the company it keeps in the message, is that it is a signed request object carrying the parameters as a JWT. Unverified, and not something you need in order to fix this error. ### 7000216 against 7000218 [7000218](https://brambrinkmeier.com/entra/aadsts/7000218/) is the same mistake on a different grant. Microsoft lists it as *"The request body must contain the following parameter: 'client_assertion' or 'client_secret'."* In our lab the two separated cleanly: | Request | Code | |---|---| | `grant_type=client_credentials`, no credential | **7000216** | | Password grant (ROPC) by a confidential client, no credential | [7000218](https://brambrinkmeier.com/entra/aadsts/7000218/) | So if you are reading a log and want to know which flow failed, 7000216 says the caller was doing client credentials. The rest of the family tells you what happened once a secret *was* sent: [7000215](https://brambrinkmeier.com/entra/aadsts/7000215/) means the secret was wrong, [7000222](https://brambrinkmeier.com/entra/aadsts/7000222/) means it had expired, and [700016](https://brambrinkmeier.com/entra/aadsts/700016/) means the app ID isn't in that tenant at all. Whether Entra treats the caller as a confidential client matters for 7000218 and is explained in Microsoft's troubleshooting article for that code: a **Web** redirect URI makes the app confidential, a **Mobile and desktop applications** redirect URI makes it public, and with no redirect URI in the request the **Allow public client flows** setting decides. The client-credentials grant has no public-client variant, so 7000216 doesn't depend on that setting. ## Reproduced in the lab On 30 October 2026 an automated lab run sent a client-credentials token request with `client_id`, `scope` and `grant_type=client_credentials`, and no credential of any kind. Entra returned: > AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. Two rounds of the run produced the same code and the same text, and the run had expected [7000218](https://brambrinkmeier.com/entra/aadsts/7000218/). In the same run a correct secret on the same app returned a token, a wrong secret returned [7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), and a password grant with no secret returned [7000218](https://brambrinkmeier.com/entra/aadsts/7000218/). The message is also complete rather than truncated, which is worth noting because the lab records only the first 160 characters of a message. No sign-in log row was captured. See [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? Usually not. It is a request that was never going to work, so it is most often a developer or deployment mistake: an empty secret variable, a configuration file that didn't load, or a secret read from a store the process can't reach. | Pattern | Likely meaning | |---|---| | A new job or container fails every run, for one app | The secret is missing from the environment or the config file. Nothing was ever sent. | | Started right after a deployment, for an app that worked before | The secret variable lost its value, or the key vault reference is unresolved. | | For one app ID, from an IP you don't own | Someone is probing with your app ID. On its own this reveals nothing to them, but check whether that IP also produced [7000215](https://brambrinkmeier.com/entra/aadsts/7000215/) or a success. | | Across many app IDs from one IP | Someone enumerating app IDs. Our reading: 7000216 tells the caller nothing about whether an app exists, since the credential check never runs. | ## How do I find it in my logs (KQL)? Which sign-in table 7000216 lands in is undocumented. Our reading: an app signing in as itself belongs in `AADServicePrincipalSignInLogs`, but since the request has no credential the service principal may not be resolved at all and nothing may be written. Check both possibilities: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType in ("7000216", "7000218") or ResultSignature in ("7000216", "7000218") | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, ResultType ``` The filter covers `ResultSignature` as well, because the two tables document the columns differently: for `SigninLogs`, `ResultType` *"provides the 5-6 digit error code that's generated during a sign-in event"*, while `AADServicePrincipalSignInLogs` describes `ResultType` as *"Success or Failure"* and `ResultSignature` as *"the error code, if any, for the sign-in operation"*. Which app and which source, so you know what to repair: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "7000216" or ResultSignature == "7000216" | summarize Failures = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), CredentialTypes = make_set(ClientCredentialType, 5), Descriptions = make_set(ResultDescription, 3) by AppId, ServicePrincipalName, IPAddress | sort by Failures desc ``` `ClientCredentialType` is documented as *"the type of client credential used. Examples include client assertion, client secret, etc."* On a request with no credential it is likely empty or absent; that is not documented, so check a row. Pair it with successes to tell a broken deployment from an unknown caller. An IP that never succeeds for the app is the one to look at: ```kusto let knownAppIPs = AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "0" or ResultType =~ "Success" | distinct AppId, IPAddress; AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "7000216" or ResultSignature == "7000216" | join kind=leftanti knownAppIPs on AppId, IPAddress | summarize Attempts = count(), LastSeen = max(TimeGenerated) by AppId, ServicePrincipalName, IPAddress | sort by Attempts desc ``` A starting threshold: a handful an hour from your own build agents is a configuration bug; a steady stream from an address you don't recognise is worth an investigation. ## How do I fix AADSTS7000216? **For developers:** 1. Put the credential in the POST body. With a secret: `client_secret=`, URL-encoded. Microsoft: *"The client secret must be URL-encoded before being sent."* Basic authentication in the `Authorization` header is also supported. 2. With a certificate or a federated credential: send `client_assertion=` and `client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer`. 3. Check the request really carries what you think. An empty environment variable produces an empty `client_secret`, which Entra reads as absent. Log the parameter names you send, never the values. 4. Keep `grant_type=client_credentials` and a `scope` that is one resource ending in `/.default`. 5. If the next error is [7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), the credential is now arriving and is wrong, which is progress. **For admins:** 1. Identify the app from the query above and tell its owner which credential is missing. 2. If the app has no usable credential at all, add one: a certificate is preferable to a secret. 3. If the failures come from an address you don't own, nothing leaked here, but treat it as probing of that app ID and check for [7000215](https://brambrinkmeier.com/entra/aadsts/7000215/) or successes from the same address. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Client-credentials token request against a lab tenant; scenario: Confidential client sends no credential). First line returned: > AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. Lab-run rows naming this code (7; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-30 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-30 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-30 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-30 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-31 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-31 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and the OAuth 2.0 client credentials flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow) 3. [Error AADSTS7000218 when a confidential client application authenticates to Microsoft Entra ID](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/confidential-client-application-authentication-error-aadsts7000218) 4. [Microsoft identity platform application authentication certificate credentials](https://learn.microsoft.com/en-us/entra/identity-platform/certificate-credentials) 5. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS7000222](https://brambrinkmeier.com/entra/aadsts/7000222/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS50027](https://brambrinkmeier.com/entra/aadsts/50027/), [AADSTS90023](https://brambrinkmeier.com/entra/aadsts/90023/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS7000216: No client credential in a client_credentials request (fix)", https://brambrinkmeier.com/entra/aadsts/7000216/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/7000218/ # AADSTS7000218: Client secret or assertion missing from the request (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/7000218/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/7000218.json **Short answer:** AADSTS7000218 means a token request reached Microsoft Entra ID as a confidential client but carried no client secret and no client assertion. Usually the app forgot the credential, or it uses ROPC, device code or IWA while the app registration is still set to confidential. Low attack value. The fix is to send the credential or, only when it fits, allow public client flows. **Fix:** Developer of a web app, API or daemon: send `client_secret` or a certificate-signed `client_assertion` in the token request. App on a user's device: register a Mobile and desktop redirect URI, or have an admin set Allow public client flows to Yes, only for a real public client. | Field | Value | |---|---| | Code | AADSTS7000218 | | Category | App configuration | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS7000218 mean? Microsoft's description: > The request body must contain the following parameter: 'client_assertion' or 'client_secret'. The reference table gives this code no PascalCase name. A token request arrived for an app that Microsoft Entra ID treats as a **confidential client**, and it carried no proof of the app's identity. Microsoft's troubleshooting article says the request fails with `invalid_client` and that confidential clients must supply a client secret or a client assertion. Two siblings help you tell the cases apart: - **[7000215](https://brambrinkmeier.com/entra/aadsts/7000215/)**: *"Invalid client secret is provided."* A secret was sent and it was wrong. - **[7000222](https://brambrinkmeier.com/entra/aadsts/7000222/)**: *"The provided client secret keys are expired."* The secret was right but expired. So 7000218 means nothing was sent at all. ### How Entra decides the client is confidential This is the part that catches most people. According to Microsoft's troubleshooting article: 1. If the request has a redirect URI, the **platform type** of that redirect URI decides. A **Web** redirect URI makes the app a confidential client. A **Mobile and desktop applications** redirect URI makes it a public client. 2. If the request has no redirect URI (ROPC, device code, Integrated Windows Authentication), Entra uses the **Allow public client flows** setting on the app registration. Yes means public, No means confidential. So a desktop tool that uses device code flow, registered with the default setting, gets 7000218 even though it was never meant to have a secret. ## Reproduced in the lab On 30 October 2026 an automated lab run created an app registration **without** public client flows enabled, then sent a password-grant (ROPC) request with no credential. Entra returned `AADSTS7000218`: > AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'. The same run also sent a client-credentials request with no credential, and that returned a different code, `AADSTS7000216` ("'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type"). So the code depends on the grant type: 7000218 comes from a user-credential flow, 7000216 from client credentials. The sign-in log row isn't captured yet; see [how pages are checked](https://brambrinkmeier.com/methodology/). In the lab tenant's sign-in logs the row appears under **User sign-ins (interactive)**, Status **Failure**, Conditional Access **Not Applied**, with the Application column naming the confidential app that sent the request without a credential. ## Is it an attack? Almost never. 7000218 is a configuration mismatch between the app and its registration. The request carried no credential, so it can't have succeeded. | Pattern | Likely meaning | |---|---| | 7000218 for a new app during testing | The developer hasn't added the secret or certificate yet, or registered the wrong platform type. | | 7000218 for a desktop script or CLI tool using device code or ROPC | The registration is confidential (public client flows set to No). Fix the registration or the flow. | | 7000218 for an app that worked yesterday | Someone changed the redirect URI platform or the public client setting, or a deployment dropped the secret from its configuration. Check the audit log for **Update application**. | | 7000218 from an IP you don't own, for your app ID | Someone outside is trying your app ID without a credential. Our interpretation: they have the client ID, which is public by design, but not the secret. Low risk on its own. | Microsoft notes that *"The client ID is a public value that identifies the application, while the client secret is a confidential value."* Knowing a client ID is not a compromise. The real security question is the fix, not the error. See the admin steps below before switching an app to a public client. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 7000218 lands in. Our reading: an app-only request (client credentials) would be a service principal sign-in, and a delegated request (device code, ROPC, authorization code) would be a user sign-in. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "7000218" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which apps hit it, from where, and since when: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "7000218" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), IPs = make_set(IPAddress, 10), Users = dcount(UserPrincipalName) by AppId, AppDisplayName = coalesce(AppDisplayName, ServicePrincipalName) | sort by Rows desc ``` If an app moved from 7000218 to success, check whether it got there by adding a secret or by being switched to a public client. The audit log shows the change to the app registration: ```kusto AuditLogs | where TimeGenerated > ago(30d) | where Category == "ApplicationManagement" | where OperationName startswith "Update application" | project TimeGenerated, OperationName, InitiatedBy, TargetResources | sort by TimeGenerated desc ``` Microsoft's audit activity reference lists both **Update application** and **Update application - Certificates and secrets management** in the ApplicationManagement category. The query uses `startswith` so it catches both; the exact punctuation in the stored `OperationName` may differ from the reference. `TargetResources` holds the changed properties, but which property names a public client switch writes isn't documented, so read the rows rather than filter on them. Service principal rows are aggregated when the service principal, status, IP address and resource match, so row counts there are not request counts. `ResultType` is a **string** column, so compare it with `"7000218"`. ## How do I fix AADSTS7000218? **For developers:** 1. If your app is a confidential client (web app, web API, daemon), send the credential. Add `client_secret`, or a `client_assertion` signed with a certificate, to the token request. Microsoft's authorization code reference says the client secret *"is required for web apps and web APIs, which can store the `client_secret` securely on the server side."* 2. If your app runs on a user's device (desktop, mobile, CLI, script), it is a public client and must not carry a secret. Microsoft: public clients *"can't be trusted to safely keep application secrets"*. Register a **Mobile and desktop applications** redirect URI, or for flows without a redirect URI, ask an admin to turn on public client flows. 3. To find out which flow your code uses, look at `grant_type` in the token request (in code or a Fiddler trace). Microsoft's article lists `password` for ROPC, `urn:ietf:params:oauth:grant-type:device_code` for device code, `authorization_code`, `client_credentials`, and `urn:ietf:params:oauth:grant-type:jwt-bearer` for on-behalf-of. **For admins:** 1. For a confidential app, the fix is a credential, not a setting. Prefer a certificate or managed identity over a secret. 2. Only for a real public client flow: in **App registrations** > the app > **Authentication** > **Advanced settings**, set **Allow public client flows** to **Yes**. Microsoft warns that this changes the client type from confidential to public, with security implications. 3. Our reading of those implications, not Microsoft's wording: once public client flows are on, anyone who knows the client ID can start ROPC or device code flows for that app without a secret. The client ID is public, so the secret no longer stands between an attacker and those flows. Don't flip the setting just to make the error go away, and don't flip it on an app that also uses a secret for server-side work. 4. If you do allow public client flows, make sure MFA and Conditional Access cover the users who sign in through that app. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Password-grant (ROPC) token request against a lab tenant; scenario: Confidential client does ROPC without a secret). First line returned: > AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'. Sign-in log row read: 2026-10-31. Lab-run rows naming this code (12; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-30 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-30 | Confidential client does ROPC without a secret | 7000218 | 7000218 | AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'. | | 2026-10-30 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-30 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-30 | Confidential client does ROPC without a secret | 7000218 | 7000218 | AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'. | | 2026-10-30 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-30 | Confidential client does ROPC without a secret | 7000218 | 7000218 | AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'. | | 2026-10-31 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-31 | Confidential client does ROPC without a secret | 7000218 | 7000218 | AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'. | | 2026-10-31 | Confidential client sends no credential | 7000218 | 7000216 | AADSTS7000216: 'client_assertion', 'client_secret' or 'request' is required for the 'client_credentials' grant type. | | 2026-10-31 | Confidential client does ROPC without a secret | 7000218 | 7000218 | AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Error AADSTS7000218 when a confidential client application authenticates to Microsoft Entra ID](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/confidential-client-application-authentication-error-aadsts7000218) 3. [Public client and confidential client applications](https://learn.microsoft.com/en-us/entra/identity-platform/msal-client-applications) 4. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow) 5. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities) 6. [Service principal sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-service-principal-sign-ins) ## Related codes [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS7000222](https://brambrinkmeier.com/entra/aadsts/7000222/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS50027](https://brambrinkmeier.com/entra/aadsts/50027/), [AADSTS70002](https://brambrinkmeier.com/entra/aadsts/70002/), [AADSTS90023](https://brambrinkmeier.com/entra/aadsts/90023/), [AADSTS90133](https://brambrinkmeier.com/entra/aadsts/90133/), [AADSTS700024](https://brambrinkmeier.com/entra/aadsts/700024/), [AADSTS1002016](https://brambrinkmeier.com/entra/aadsts/1002016/), [AADSTS5002730](https://brambrinkmeier.com/entra/aadsts/5002730/), [AADSTS7000216](https://brambrinkmeier.com/entra/aadsts/7000216/), [AADSTS9002326](https://brambrinkmeier.com/entra/aadsts/9002326/), [AADSTS9002327](https://brambrinkmeier.com/entra/aadsts/9002327/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS7000218: Client secret or assertion missing from the request (fix)", https://brambrinkmeier.com/entra/aadsts/7000218/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/7000222/ # AADSTS7000222: The provided client secret keys are expired Canonical: https://brambrinkmeier.com/entra/aadsts/7000222/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/7000222.json **Short answer:** AADSTS7000222 means an app or service principal sent a client secret that has passed its expiry date. It is almost always a missed rotation, not an attack. The security angle is secret hygiene: an expired secret still sitting in config files shows where secrets live. Microsoft recommends managed identities or certificates instead. Hunt it in AADServicePrincipalSignInLogs. **Fix:** Developer: create a new credential on the app registration's Certificates and secrets page and update every system that uses it. Admin: find every IP still sending the expired secret, update those systems, then remove the expired secret. Move to a managed identity or certificate where you can. | Field | Value | |---|---| | Code | AADSTS7000222 | | Microsoft name | InvalidClientSecretExpiredKeysProvided | | Category | App configuration | | Type | Failure | | Attack signal | Low: usually configuration or user error | | Where to look | `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-24 | ## What does AADSTS7000222 mean? Microsoft's description: > **InvalidClientSecretExpiredKeysProvided**: The provided client secret keys are expired. Create new keys for your app, or consider using certificate credentials for added security An app tried to get a token with a client secret that was valid once but has passed its end date. The secret itself was right. Nobody replaced it in time. Two siblings help you tell the cases apart: - **[7000215](https://brambrinkmeier.com/entra/aadsts/7000215/)**: *"Invalid client secret is provided."* A secret was sent and it was wrong. - **7000218**: *"The request body must contain the following parameter: 'client_assertion' or 'client_secret'."* No secret or assertion was sent at all. ## Is it an attack? Almost never. 7000222 is what a missed rotation looks like: a script, scheduled job or integration still holds a secret that expired. It usually shows up as a sudden outage of that integration. | Pattern | Likely meaning | |---|---| | 7000222 for one app from your own servers, starting on a specific day | The secret expired that day and nobody rotated it. Benign, but the integration is broken. | | 7000222 from your own servers after you created a new secret | You added a new secret but missed one system that still holds the old one. | | 7000222 for an app from an IP you don't own | Someone outside holds a copy of an old secret for your app. Our interpretation, not a Microsoft statement: the expiry stopped them, but the secret leaked at some point. Find out where it was stored. | The useful security reading is the third row and the inventory it gives you. Every IP that sends an expired secret is a place where that secret was stored. If one of those systems was compromised, read [hunting credential reuse after a web-server breach](https://brambrinkmeier.com/guides/hunt-credential-reuse-after-web-server-breach/) for which other secrets to rotate. ## How do I find it in my logs (KQL)? Which apps are failing, and from where: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "7000222" | summarize Attempts = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), KeyIds = make_set(ServicePrincipalCredentialKeyId, 10) by AppId, ServicePrincipalName, IPAddress | sort by Attempts desc ``` Expired-secret attempts from IPs that never had a success for the same app in the last 30 days: ```kusto let knownAppIPs = AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "0" | distinct AppId, IPAddress; AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "7000222" | join kind=leftanti knownAppIPs on AppId, IPAddress | summarize Attempts = count(), LastSeen = max(TimeGenerated) by AppId, ServicePrincipalName, IPAddress | sort by Attempts desc ``` Check two things in your own workspace before relying on these queries: - The Azure Monitor reference for `AADServicePrincipalSignInLogs` describes `ResultType` as *"Success or Failure"*, while the user sign-in tables document it as the numeric error code as a string. Look at a few failed rows and confirm they carry `"7000222"` and that successes carry `"0"`. If they don't, filter on `ResultSignature` instead. - Whether `ServicePrincipalCredentialKeyId` is filled in on an expired-secret failure isn't documented. If it is, it tells you exactly which secret is still in use, which makes cleanup easy. A secret used by a confidential client in a delegated (user) flow may surface in the user sign-in tables instead. That is our reading of how the flows work, not a documented statement. If the first query returns nothing but users report the error, search `SigninLogs` for the same `ResultType`. ## How does Conditional Access affect it? - 7000222 is a failed credential check, so no policy grants or blocks it. Conditional Access for workload identities can't fix an expired secret. - Microsoft notes that workload identities *"Can't perform multifactor authentication"* and *"Need to store their credentials or secrets somewhere."* The control that matters is the credential type. - Conditional Access for workload identities can add location and risk conditions to single-tenant service principals, which limits where a leaked secret works. It needs Workload Identities Premium licenses. ## How do I fix AADSTS7000222? **For developers:** create a new credential on the app registration's **Certificates and secrets** page and update every system that uses it. Don't stop at the first system that works again. **For admins:** 1. Use the first query to list every IP still sending the expired secret, and update or retire each of those systems. 2. Remove the expired secret from the app registration once nothing uses it. Microsoft: *"An unused credential on an application can result in a security breach."* 3. Move away from secrets. Microsoft's order of preference is a managed identity first, then certificate credentials: *"Don't use password credentials, also known as secrets."* Certificate credentials work *"anywhere a client secret could be used"*, including the client credentials flow. 4. Use application management policies to limit secret lifetimes or block new secrets, so the next rotation is planned rather than an outage. 5. If the second query returns an IP you don't own, treat every credential that was stored alongside that secret as exposed. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Security best practices for application properties](https://learn.microsoft.com/en-us/entra/identity-platform/security-best-practices-for-app-registration) 3. [Microsoft identity platform application authentication certificate credentials](https://learn.microsoft.com/en-us/entra/identity-platform/certificate-credentials) 4. [Conditional Access for workload identities](https://learn.microsoft.com/en-us/entra/identity/conditional-access/workload-identity) 5. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS70002](https://brambrinkmeier.com/entra/aadsts/70002/), [AADSTS700024](https://brambrinkmeier.com/entra/aadsts/700024/), [AADSTS5002730](https://brambrinkmeier.com/entra/aadsts/5002730/), [AADSTS7000216](https://brambrinkmeier.com/entra/aadsts/7000216/), [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS7000222: The provided client secret keys are expired", https://brambrinkmeier.com/entra/aadsts/7000222/ (CC BY 4.0), last updated 2026-10-24. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/7002121/ # AADSTS7002121: Federated credential audience doesn't match the assertion (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/7002121/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/7002121.json **Short answer:** AADSTS7002121 means a workload presented an external token whose aud claim matches no federated identity credential on the app or managed identity. Microsoft's error reference doesn't list it. Usually the token was requested for the wrong audience instead of api://AzureADTokenExchange, or the case differs. It is a configuration error with low attack value. **Fix:** Pipeline owner: read the audience from the error message or the token's `aud` claim, and request the token for `api://AzureADTokenExchange`, in that exact case. Admin: check the single audience value on the federated identity credential and make every workload that uses it ask for the same string. | Field | Value | |---|---| | Code | AADSTS7002121 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | Where to look | `AADServicePrincipalSignInLogs` | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS7002121 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS7002121 (checked 30 October 2026). We found no other Microsoft page that names it either. The wording below is from a lab run, not from a Microsoft page. A federated identity credential on an app registration or a user-assigned managed identity says which external token Entra will exchange for an access token. It pins three values: issuer, subject and audience. 7002121 is the audience failing to match. Microsoft's Graph overview describes the property: **audiences** is *"the audience that can appear in the external token"*, it *"says what Microsoft identity platform should accept in the `aud` claim in the incoming token"*, and it *"should be set to `api://AzureADTokenExchange` for Microsoft Entra ID"*. The restrictions page adds *"You must add a single audience value, which has a limit of 600 characters"*, and lists the error a wrong count gives at configuration time: *"Federated identity credentials must have exactly one audience."* The accepted value depends on the cloud. For a managed identity acting as the credential, Microsoft lists: | Cloud | Audience value | |---|---| | Microsoft Entra ID global service | `api://AzureADTokenExchange` | | Microsoft Entra ID for US Government | `api://AzureADTokenExchangeUSGov` | | Microsoft Entra China operated by 21Vianet | `api://AzureADTokenExchangeChina` | Matching is case-sensitive. Microsoft's breaking-changes page, under *"Federated Identity Credentials now use case-sensitive matching"* with an effective date of September 2024: *"Previously, when matching the Federated Identity Credential (FIC) `issuer`, `subject`, and `audience` values against the corresponding `issuer`, `subject`, and `audience` values contained in the token sent to Microsoft Entra ID by an external IdP, case-insensitive matching was used. To provide more fine-grained control to customers, we're switching to enforcing case-sensitive matching."* The siblings tell you which of the three values failed: - [700211](https://brambrinkmeier.com/entra/aadsts/700211/) issuer doesn't match - [700213](https://brambrinkmeier.com/entra/aadsts/700213/) subject doesn't match - [7002138](https://brambrinkmeier.com/entra/aadsts/7002138/) subject matches except for case - [700212](https://brambrinkmeier.com/entra/aadsts/700212/) audience doesn't match, in user reports - [70025](https://brambrinkmeier.com/entra/aadsts/70025/) the app has no federated credentials at all [700212](https://brambrinkmeier.com/entra/aadsts/700212/) carries almost the same message text and the same meaning. Users report 700212; our lab tenant returned 7002121 for the audience case on 30 October 2026. We can't tell from one tenant whether 700212 is older, cloud-specific or issuer-specific, so treat the two as one condition and match on both in detections. ## Reproduced in the lab On 30 October 2026 an automated lab run created an app registration with a federated identity credential, then presented a token whose `aud` claim was a GUID rather than the credential's configured audience. Entra returned `AADSTS7002121`: > AADSTS7002121: No matching federated identity record found for presented assertion audience '\'. The Audience for the federat... The lab records only the first line of `error_description`, cut at about 160 characters, so the sentence about the configured audience is truncated. The same run confirmed the siblings on the same app: a wrong issuer gave [700211](https://brambrinkmeier.com/entra/aadsts/700211/), a wrong subject gave [700213](https://brambrinkmeier.com/entra/aadsts/700213/), a subject differing only in case gave [7002138](https://brambrinkmeier.com/entra/aadsts/7002138/), and an app with no credential at all gave [70025](https://brambrinkmeier.com/entra/aadsts/70025/). So Entra does distinguish the three fields, and 7002121 is specifically the audience. No sign-in log row was captured. See [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? No. The workload asked its own identity provider for a token meant for something else, or the credential and the workload disagree about the audience string. | Pattern | Likely meaning | |---|---| | A new pipeline or workload fails on its first federated run | The token is requested for the provider's default audience rather than `api://AzureADTokenExchange`. | | Kubernetes pod fails and the audience in the error is a cluster URL | The pod is using its default service account token, not one projected for the credential's audience. | | Works in the commercial cloud, fails in US Government or China | The audience must be that cloud's value from the table above. | | Only the case differs | Matching has been case-sensitive since the September 2024 change. Fix the case on whichever side is wrong. | | The error appears right after someone edited the credential | The audience was changed on one side only. A credential holds exactly one audience value. | ## How do I find it in my logs (KQL)? Which sign-in table 7002121 lands in is undocumented. Our reading: an app registration's token request lands in `AADServicePrincipalSignInLogs`, and a user-assigned managed identity presenting the token may land in the managed identity sign-in log instead. Start with a union so you don't miss it: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs, AADManagedIdentitySignInLogs | where TimeGenerated > ago(30d) | where ResultType in ("7002121", "700212") or ResultSignature in ("7002121", "700212") | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable, ResultType ``` The query filters `ResultSignature` as well as `ResultType` because the two tables document the column differently. For `SigninLogs`, `ResultType` *"provides the 5-6 digit error code that's generated during a sign-in event"*; for `AADServicePrincipalSignInLogs` it is described only as *"Success or Failure"*, with `ResultSignature` holding *"the error code, if any, for the sign-in operation"*. Look at one failed row in your own workspace and keep the filter that matches. Which app and which credential, with the error text: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType in ("7002121", "700212") or ResultSignature in ("7002121", "700212") | summarize Failures = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Credentials = make_set(FederatedCredentialId, 5), CredentialTypes = make_set(ClientCredentialType, 5), Descriptions = make_set(ResultDescription, 5), IPs = make_set(IPAddress, 10) by AppId, ServicePrincipalName | sort by Failures desc ``` `FederatedCredentialId` is documented as *"Th identifier of an application's federated identity credential if a federated identity credential was used to sign in"* (the typo is Microsoft's), and `ClientCredentialType` as *"the type of client credential used"*. Whether either column is filled in when the match fails is not documented; check a row before building a rule on it. The same goes for whether `ResultDescription` carries the presented audience. A failing workload that also succeeds tells you the audience it should be sending. Compare the two: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where AppId == "" | summarize Rows = count(), LastSeen = max(TimeGenerated) by ResultType, ResultSignature, FederatedCredentialId, ClientCredentialType | sort by LastSeen desc ``` A starting point for alerting: more than about 20 of these in an hour for one app usually means a deployment went out with the wrong audience, not an attack. ## How do I fix AADSTS7002121? **For developers and pipeline owners:** 1. Read the audience out of the error message, or decode the token your workload presents and read its `aud` claim. 2. Request the token for `api://AzureADTokenExchange`, in that exact case, unless your credential deliberately uses another value. Use the cloud-specific value from the table above outside the commercial cloud. 3. Kubernetes: mount a projected service account token with that audience instead of the pod's default token. 4. GitHub Actions and Azure DevOps: leave the audience input of the login step at its default unless the credential says otherwise. 5. If the issuer or the subject is also wrong, you will see [700211](https://brambrinkmeier.com/entra/aadsts/700211/) or [700213](https://brambrinkmeier.com/entra/aadsts/700213/) next. Fix all three against the values in the error messages. **For admins:** 1. Open the app registration or managed identity, **Certificates & secrets** > **Federated credentials**, and read the audience. It holds exactly one value. 2. If you changed it from `api://AzureADTokenExchange`, every workload using that credential must request the same string, in the same case. 3. Don't fix a case mismatch by recreating the credential with a different case. Fix whichever side is wrong and leave the other alone, so the other workloads using it keep working. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Client-credentials token request with a federated identity credential, against a lab tenant; scenario: Federated credential: audience does not match). First line returned: > AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat Lab-run rows naming this code (5; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-30 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-31 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | | 2026-10-31 | Federated credential: audience does not match | 700212 / 700213 / 70021 | 7002121 | AADSTS7002121: No matching federated identity record found for presented assertion audience '{audience-id}'. The Audience for the federat | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Important considerations and restrictions for federated identity credentials](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-considerations) 3. [Overview of federated identity credentials (Microsoft Graph)](https://learn.microsoft.com/en-us/graph/api/resources/federatedidentitycredentials-overview) 4. [Configure an application to trust a managed identity](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-config-app-trust-managed-identity) 5. [Microsoft Entra breaking changes: Federated Identity Credentials now use case-sensitive matching](https://learn.microsoft.com/en-us/entra/identity-platform/reference-breaking-changes) 6. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS700212](https://brambrinkmeier.com/entra/aadsts/700212/), [AADSTS700211](https://brambrinkmeier.com/entra/aadsts/700211/), [AADSTS700213](https://brambrinkmeier.com/entra/aadsts/700213/), [AADSTS7002138](https://brambrinkmeier.com/entra/aadsts/7002138/), [AADSTS70025](https://brambrinkmeier.com/entra/aadsts/70025/), [AADSTS700226](https://brambrinkmeier.com/entra/aadsts/700226/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS7002121: Federated credential audience doesn't match the assertion (fix)", https://brambrinkmeier.com/entra/aadsts/7002121/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/7002138/ # AADSTS7002138: Federated credential subject differs in case (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/7002138/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/7002138.json **Short answer:** AADSTS7002138 means the subject in a workload's external token matches a federated identity credential only when letter case is ignored. Since Microsoft's 2024 change, matching is case-sensitive, so the exchange fails. Typical case: a GitHub environment named Production while the credential says production. A configuration error with low attack value. **Fix:** Pipeline owner: copy the subject from the error or the run log (`subject claim`) and set the federated credential's subject to that exact string, same case. Or change the workflow to match the credential, for example rename the GitHub environment from `Production` to `production`. | Field | Value | |---|---| | Code | AADSTS7002138 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS7002138 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS7002138 (checked 30 October 2026). The README of Microsoft's `Azure/login` GitHub Action documents it in its troubleshooting section: > Error: AADSTS7002138: No matching federated identity record found for presented assertion subject 'repo:<org>/<repo>:ref:refs/heads/main'. The subject matches with case-insensitive comparison, but not with case-sensitive comparison. A user on Microsoft Q&A posted the full response, which goes on: > …Check your federated identity credential Subject, Audience and Issuer against the presented assertion. See documentation at: https://learn.microsoft.com/entra/workload-id/workload-identity-federation. See breaking change notification and remediation at: https://learn.microsoft.com/en-us/entra/identity-platform/reference-breaking-changes#august-2024. The breaking change it points to: in August 2024 Microsoft announced that federated identity credential `issuer`, `subject` and `audience` values are matched case-sensitively, where they used to be matched case-insensitively. Microsoft's invalid example: - Token subject: `repo:contoso/contoso-org:ref:refs/heads/main` - FIC subject: `repo:Contoso/Contoso-Org:ref:refs/heads/main` The notice rolled the change out in stages: first to apps and managed identities created after 14 August 2024, then to inactive ones from 27 September 2024, and *"For active applications, case-sensitive matching comes at a later date to be communicated."* That explains setups that ran for years and then broke with no change on your side. Our reading: 7002138 is a more specific form of [700213](https://brambrinkmeier.com/entra/aadsts/700213/). The notice itself said the 700213 message would be revamped to mention case. 7002138 goes further and tells you case is the *only* difference. Microsoft doesn't document whether there are matching codes for issuer or audience that differ only in case; the case-only codes we found all concern the subject. See [70021](https://brambrinkmeier.com/entra/aadsts/70021/) for the general no-match code and [700211](https://brambrinkmeier.com/entra/aadsts/700211/) and [700212](https://brambrinkmeier.com/entra/aadsts/700212/) for issuer and audience. ## Reproduced in the lab On 30 October 2026 an automated lab run set this up in my own tenant: one app registration presents its access token as a client assertion, and a second app carries the federated identity credential that is supposed to accept it. With the credential's subject set to the **same value in different capitals**, Entra returned `AADSTS7002138` rather than 700213: > AADSTS7002138: No matching federated identity record found for presented assertion subject ''. The subject matches with case-insensitive comparison, but not with case-sensitive comparison. That confirms the split in practice: a subject that is wrong gives [700213](https://brambrinkmeier.com/entra/aadsts/700213/), and a subject that is right apart from capitals gives this code. If you see 7002138, the value is correct and only the case is off, which is usually an environment name such as `Production` against `production`. The sign-in log row isn't captured yet; see [how pages are checked](https://brambrinkmeier.com/methodology/). ## Is it an attack? No. Entra found a credential that would have matched before the 2024 change. The fix is the casing. | Pattern | Likely meaning | |---|---| | A GitHub workflow uses `environment: Production` and the error shows `:environment:Production` | The credential says `production`, or the other way round. On the Q&A thread, the top answer fixed it by renaming the environment to lowercase. Microsoft's notice gives the same advice for Azure App Service users. | | The org or repo name has capitals | GitHub sends the casing it holds. The README: uppercase characters in the org, repo, branch or environment name must match the `subject claim` in the run log. | | Deployments broke without anyone changing the workflow | The staged rollout above reached your app. | | It still fails after "fixing" the case | Users report puzzling cases where the subject looks identical (Azure/login issue 573). Copy the subject from the log rather than retyping it. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 7002138 lands in. Our reading: app registration failures land in `AADServicePrincipalSignInLogs`; a user-assigned managed identity may log in the managed identity sign-in log instead. Check: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "7002138" or ResultSignature == "7002138" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable ``` To catch every app hit by the case change, list both codes together. If `ResultDescription` holds the returned message (our assumption; check a row), it shows the subject with the casing the token used: ```kusto AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType in ("7002138", "700213") or ResultSignature in ("7002138", "700213") | summarize Failures = count(), LastSeen = max(TimeGenerated), Codes = make_set(ResultType, 5), Descriptions = make_set(ResultDescription, 5) by AppId, ServicePrincipalName | sort by LastSeen desc ``` ## How do I fix AADSTS7002138? **For developers and pipeline owners:** 1. Copy the subject from the error or from the run log (`Federated token details`, `subject claim`). 2. Either update the credential's subject to that exact string, or change the workflow so the token carries the credential's casing. Microsoft's notice: *"replace the current `issuer`, `subject`, or `audience` value in the FIC with the `issuer`, `subject`, or `audience` value that was contained in the error message."* 3. For a GitHub environment, renaming it in the workflow (for example `Production` to `production`) is the fix users report and Microsoft suggests for App Service. **For admins:** 1. Use the query above to find every app still failing, and fix the credentials in one go. 2. Microsoft's overview now states the rule plainly: the values *"must case-sensitively match"*. Copy values from tokens or logs, never type them by hand. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Client-credentials token request with a federated identity credential, against a lab tenant; scenario: Federated credential: subject differs only by case). First line returned: > AADSTS7002138: No matching federated identity record found for presented assertion subject ''. The subject matches with case-insensitive comparison, but not with case-sensitive comparison. Lab-run rows naming this code (5; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Federated credential: subject differs only by case | 7002138 / 700213 | 7002138 | AADSTS7002138: No matching federated identity record found for presented assertion subject '{guid}'. The subject matches with case | | 2026-10-30 | Federated credential: subject differs only by case | 7002138 / 700213 | 7002138 | AADSTS7002138: No matching federated identity record found for presented assertion subject '{guid}'. The subject matches with case | | 2026-10-30 | Federated credential: subject differs only by case | 7002138 / 700213 | 7002138 | AADSTS7002138: No matching federated identity record found for presented assertion subject '{guid}'. The subject matches with case | | 2026-10-31 | Federated credential: subject differs only by case | 7002138 / 700213 | 7002138 | AADSTS7002138: No matching federated identity record found for presented assertion subject '{guid}'. The subject matches with case | | 2026-10-31 | Federated credential: subject differs only by case | 7002138 / 700213 | 7002138 | AADSTS7002138: No matching federated identity record found for presented assertion subject '{guid}'. The subject matches with case | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/lb-lu/entra/identity-platform/reference-error-codes) 2. [Azure/login GitHub Action README](https://github.com/Azure/login#readme) 3. [Federated identity credentials and case-sensitive matching (Microsoft Entra breaking changes, August 2024)](https://learn.microsoft.com/en-us/entra/identity-platform/reference-breaking-changes) 4. [Github quit deploying to azure (Microsoft Q&A)](https://learn.microsoft.com/en-us/answers/questions/2181284/github-quit-deploying-to-azure) 5. [Federated credentials does not work on main branch (Azure/login issue 573)](https://github.com/Azure/login/issues/573) 6. [Workload identity federation](https://learn.microsoft.com/entra/workload-id/workload-identity-federation) 7. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS700213](https://brambrinkmeier.com/entra/aadsts/700213/), [AADSTS70021](https://brambrinkmeier.com/entra/aadsts/70021/), [AADSTS700211](https://brambrinkmeier.com/entra/aadsts/700211/), [AADSTS700212](https://brambrinkmeier.com/entra/aadsts/700212/), [AADSTS70025](https://brambrinkmeier.com/entra/aadsts/70025/), [AADSTS7002121](https://brambrinkmeier.com/entra/aadsts/7002121/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS7002138: Federated credential subject differs in case (fix)", https://brambrinkmeier.com/entra/aadsts/7002138/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/9002313/ # AADSTS9002313: Request is malformed or invalid (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/9002313/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/9002313.json **Short answer:** AADSTS9002313 means Microsoft Entra ID couldn't process a sign-in or token request because the request itself was malformed. It is a developer or integration error, not a credential failure. Microsoft's own advice is to capture a Fiddler trace and check how the request is built. It has low attack value. Find which app sends the bad requests and fix the request. **Fix:** Developer: capture the failing request with Fiddler or browser developer tools and check it parameter by parameter against the endpoint's protocol reference; use MSAL instead of hand-written requests. Admin: find the app and start date with the second query and give both to the app owner or vendor. | Field | Value | |---|---| | Code | AADSTS9002313 | | Microsoft name | InvalidRequest | | Category | App configuration | | Type | Failure | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS9002313 mean? Microsoft's description: > **InvalidRequest**: Request is malformed or invalid. - The issue arises because there was something wrong with the request to a certain endpoint. The suggestion to this issue is to get a fiddler trace of the error occurring and looking to see if the request is properly formatted or not. The request never got as far as checking a password or a secret. Something in how it was built was wrong, so Microsoft Entra ID rejected it as a request. Microsoft's description doesn't say which part of the request is wrong. That is the hard part of this code: it is generic. The OAuth 2.0 protocol error that goes with this kind of problem is `invalid_request`, which the authorization code flow reference describes as a *"Protocol error, such as a missing required parameter."* Its advice for the client: *"Fix and resubmit the request. This error is a development error typically caught during initial testing."* Our reading is that 9002313 is the AADSTS code behind many of those `invalid_request` responses, but Microsoft doesn't publish that mapping. ## Is it an attack? Almost never. A malformed request gets the sender nothing, and Microsoft treats the code as a request-formatting problem. | Pattern | Likely meaning | |---|---| | 9002313 for one app, starting right after a deployment or library update | The new version builds its requests differently. A regression in the app. | | 9002313 for every user of one app, from the start | The integration was never built correctly. Common with hand-written OAuth code. | | 9002313 for one user only | Something specific to that user's request, such as a stale bookmark to a sign-in URL or a broken browser extension. Likely, but unconfirmed. | | 9002313 from an IP you don't know, for an app ID you don't recognise | Someone's tooling is building bad requests against your tenant. Our interpretation: it is worth a look at what else that IP did, but the 9002313 itself is not harmful. | There is no documented attack pattern for 9002313. Keep it out of password spray detections, because it says nothing about credentials. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 9002313 is logged in, or whether every malformed request produces a sign-in log row at all. Start by checking where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "9002313" | summarize Rows = count(), Apps = dcount(AppId) by SourceTable ``` Which apps send the malformed requests, and since when. A sudden start date usually points at a release: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "9002313" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), IPs = dcount(IPAddress), Descriptions = make_set(ResultDescription, 5) by AppId, AppDisplayName = coalesce(AppDisplayName, ServicePrincipalName) | sort by Rows desc ``` Check `ResultDescription` in the output. It may carry more detail than the generic reference text, such as the name of the parameter that was wrong. Whether it does isn't documented, so treat it as a bonus if it's there. Non-interactive and service principal rows are aggregated when application, user (or service principal), IP address, status and resource match, so row counts in those tables are not request counts. `ResultType` is a **string** column, so compare it with `"9002313"`, not `9002313`. ## How do I fix AADSTS9002313? **For the user:** this isn't something you caused with your password. If an old bookmark or saved link starts the sign-in, open the app from its normal start page instead. If the error stays, report it to whoever runs the app with the time it happened. **For developers:** 1. Do what Microsoft suggests: capture the failing request with Fiddler (or your browser's developer tools) and check it parameter by parameter against the protocol reference for that endpoint. 2. Check that the request goes to the right endpoint for its parameters. A v2.0 parameter such as `scope` sent to a v1 endpoint, or the reverse, is a typical way to build an invalid request. That is our example, not one Microsoft lists for this code. 3. Check encoding. Values in a token request body must be form-encoded; a raw `+`, `&` or space in a secret or redirect URI breaks the request. Again our example, not a Microsoft statement. 4. Prefer a Microsoft Authentication Library (MSAL) over hand-written requests. It builds the protocol messages for you. **For admins:** 1. Use the second query to find the app and the date it started. Hand both to the app owner or vendor. 2. If the app is a third-party SaaS integration, the request is built on the vendor side. Open a ticket with them and include the correlation ID and timestamp from the sign-in log row. 3. If the app ID is unknown to you, check whether it has a service principal in your tenant before deciding it is harmless. A related code for an app that isn't there is [700016](https://brambrinkmeier.com/entra/aadsts/700016/). ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. Lab-run rows naming this code (22; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-30 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-30 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-30 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-30 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-30 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-30 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-30 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-30 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-30 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-30 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-30 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-31 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-31 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-31 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | | 2026-10-31 | Device code that was never issued | 70020 / 70000 / 9002313 | 7000014 | AADSTS7000014: The provided value for the input parameter 'device_code' is not valid. | | 2026-10-31 | Client assertion that is not a JWT | 9002313 / 50027 / 700027 | 50027 | AADSTS50027: JWT token is invalid or malformed. | | 2026-10-31 | Unknown client_assertion_type | 9002313 / 700027 | 90023 | AADSTS90023: Unexpected client assertion type. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow) 3. [Non-interactive user sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-noninteractive-sign-ins) 4. [Service principal sign-ins](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-service-principal-sign-ins) ## Related codes [AADSTS50011](https://brambrinkmeier.com/entra/aadsts/50011/), [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS90014](https://brambrinkmeier.com/entra/aadsts/90014/), [AADSTS90015](https://brambrinkmeier.com/entra/aadsts/90015/), [AADSTS750054](https://brambrinkmeier.com/entra/aadsts/750054/), [AADSTS900023](https://brambrinkmeier.com/entra/aadsts/900023/), [AADSTS900561](https://brambrinkmeier.com/entra/aadsts/900561/), [AADSTS901002](https://brambrinkmeier.com/entra/aadsts/901002/), [AADSTS1002016](https://brambrinkmeier.com/entra/aadsts/1002016/), [AADSTS7000014](https://brambrinkmeier.com/entra/aadsts/7000014/), [AADSTS9002326](https://brambrinkmeier.com/entra/aadsts/9002326/), [AADSTS9002327](https://brambrinkmeier.com/entra/aadsts/9002327/), [AADSTS9002331](https://brambrinkmeier.com/entra/aadsts/9002331/), [AADSTS9010010](https://brambrinkmeier.com/entra/aadsts/9010010/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS9002313: Request is malformed or invalid (fix)", https://brambrinkmeier.com/entra/aadsts/9002313/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/9002326/ # AADSTS9002326: Cross-origin token request from a non-SPA app (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/9002326/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/9002326.json **Short answer:** AADSTS9002326 means a browser sent a token request (it carried an Origin header) for an app that isn't registered as a single-page application. Microsoft's error reference doesn't list it. Typical causes: client credentials or a secret called from JavaScript, or an SPA whose redirect URI isn't the spa type. Low attack value. Fix the app registration or move the call to a backend. **Fix:** Developer: for an SPA, register the redirect URI under Single-page application, not Web, and use auth code flow with PKCE (MSAL.js). If browser code calls `client_credentials` or sends a secret, move that call to a backend and rotate the secret. User: report the app, page and time to its owner. | Field | Value | |---|---| | Code | AADSTS9002326 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS9002326 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS9002326 (checked 30 October 2026). The lab reproduced it. A password-grant token request from a public client, sent with the header `Origin: https://lab.brambrinkmeier.com`, returned: > AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Request origin: 'https://lab.brambrinkmeier.com'. Entra treats a token request that carries an `Origin` header as one made from a browser. It accepts such a request only when the app is set up as a single-page application (SPA). Microsoft's wording below links the header to the browser. Microsoft describes the message, without the code number, in its authorization code flow reference: > Single page apps may receive an `invalid_request` error indicating that cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. This indicates that the redirect URI used to request the token has not been marked as a `spa` redirect URI. The same page explains why the check exists: > Applications can't use a `spa` redirect URI with non-SPA flows, for example, native applications or client credential flows. [...] the Microsoft identity platform also prevents the use of client credentials in all flows in the presence of an `Origin` header, to ensure that secrets aren't used from within the browser. Our reading of the lab result: the check is not only about secrets. The lab request used the password grant from a public client, with no secret, and still got 9002326. So any token request with an `Origin` header from an app that isn't an SPA can hit it. ## Reproduced in the lab On 30 October 2026 an automated lab run sent a password-grant (ROPC) token request from a public client app in my lab tenant. The request carried the header `Origin: https://lab.brambrinkmeier.com`. Entra returned `AADSTS9002326` with the first line quoted above. That confirms the code and its wording at the token endpoint. The message names the origin it saw, which helps you find the page that sent the call. It lands in **`SigninLogs`** (interactive user sign-ins): one row per lab run, Status Failure, Conditional Access Not Applied, client app "Mobile Apps and Desktop clients". Entra's explanation on the row (the "additional details" field) reads: *"The application must fix either the reply URIs registered on the application registration to include a unique reply address of type "spa", or they must fix the token request to not include an Origin header, if being sent from a non-browser client."* That is Microsoft's own description of the fix, which its error reference doesn't carry. The KQL below was run on these rows ([how](https://brambrinkmeier.com/methodology/)). Both queries found the lab rows. ## Is it an attack? Almost always no. It is a mismatch between where the code runs (a browser) and how the app is registered. | Pattern | Likely meaning | |---|---| | Works in Postman, fails from the web page | Users report exactly this ([Q&A 1534740](https://learn.microsoft.com/en-us/answers/questions/1534740/cross-origin-token-redemption-is-permitted-only-fo), [Q&A 1608608](https://learn.microsoft.com/en-us/answers/questions/1608608/cross-origin-token-redemption-is-permitted-only-fo)). Our reading: Postman sends no `Origin` header; the browser does. | | A script on a SharePoint page or a front end calls `client_credentials` with a secret | Users report it on this call (Q&A 1534740). The secret is in browser code, which Microsoft blocks on purpose. Treat the secret as exposed. | | An SPA using MSAL.js fails on the code redemption step | The redirect URI is registered as **Web**, not **Single-page application**. This is the cause Microsoft describes. | | A hybrid mobile app (Ionic/Capacitor) fails with origin `capacitor://localhost` | Users report it ([Ionic forum](https://forum.ionicframework.com/t/capacitor-msal-azure-b2c-ios-not-working-aadsts9002326/240436)). Likely the app's web view sends an `Origin` header, so Entra treats it as a browser (unconfirmed). | As far as we can tell, the error gives an attacker nothing. The request fails before a token is issued. The one security point is the second row. If a client secret sits in JavaScript, anyone who opens the page can read it. Rotate it. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 9002326 is logged in. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "9002326" | summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable, AppId ``` Which apps fail, and from which clients. `UserAgent` often tells you it is a browser: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "9002326" | summarize Rows = count(), IPs = dcount(IPAddress), Agents = make_set(UserAgent, 5), Descriptions = make_set(ResultDescription, 3) by SourceTable, AppId | sort by Rows desc ``` If both queries return nothing, the rows may not be written to your tenant's logs at all. That is also undocumented. The message itself, with its `Request origin`, is then your best evidence. ## How do I fix AADSTS9002326? **For the user:** you can't fix this yourself. Report the app name, the page you were on and the time to whoever runs the app. **For developers:** 1. **If the app is an SPA**, register the redirect URI under **Authentication** > **Add a platform** > **Single-page application**, not under **Web**. Microsoft's auth code flow page says to *"update the redirect URI for your app to use the `spa` type"*. Use the authorization code flow with PKCE, for example with MSAL.js. Microsoft notes PKCE is *"required by the Microsoft identity platform for single page apps using the authorization code flow"*. 2. **If browser code calls `client_credentials` or sends a client secret**, move that call to a backend. Microsoft's guidance is plain: *"Don't use the application secret in a native app or single page app because a `client_secret` can't be reliably stored on devices or web pages."* The browser then calls your backend, and the backend calls Entra. 3. **If browser code uses the password grant**, stop. Use an interactive sign-in with MSAL.js instead. 4. **For hybrid mobile apps**, our reading is that the web view counts as a browser. Either register the app as an SPA and use a browser-style flow, or use a native MSAL library so the token request doesn't come from the web view. Test both; the Ionic thread has no replies and no confirmed fix. **For admins:** 1. Look up the app by the `AppId` from the queries, or by the client ID in the error. 2. In **App registrations** > the app > **Authentication**, check which platform the redirect URI is under. 3. If the app had a secret in browser code, create a new secret, update the backend that should hold it, and delete the old one. ## Evidence Reproduced in a lab tenant on 2026-10-30 (ROPC and other token-endpoint requests against a lab tenant; scenario: Token request with a browser Origin header from a non-SPA client). First line returned: > AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Request origin: 'https://lab.brambrinkmeier.com'. Sign-in log row read: 2026-10-30. KQL run against the exported lab rows: 2026-10-30. Lab-run rows naming this code (8; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Token request with a browser Origin header from a non-SPA client | 9002326 | 9002326 | AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Request origin: 'https://lab.brambrinkmeier.com'. | | 2026-10-30 | Token request with a browser Origin header from a non-SPA client | 9002326 | 9002326 | AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Request origin: 'https://lab.brambrinkmeier.com'. | | 2026-10-30 | Token request with a browser Origin header from a non-SPA client | 9002326 | 9002326 | AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Request origin: 'https://lab.brambrinkmeier.com'. | | 2026-10-30 | Token request with a browser Origin header from a non-SPA client | 9002326 | 9002326 | AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Request origin: 'https://lab.brambrinkmeier.com'. | | 2026-10-30 | Token request with a browser Origin header from a non-SPA client | 9002326 | 9002326 | AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Request origin: 'https://lab.brambrinkmeier.com'. | | 2026-10-30 | Token request with a browser Origin header from a non-SPA client | 9002326 | 9002326 | AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Request origin: 'https://lab.brambrinkmeier.com'. | | 2026-10-31 | Token request with a browser Origin header from a non-SPA client | 9002326 | 9002326 | AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Request origin: 'https://lab.brambrinkmeier.com'. | | 2026-10-31 | Token request with a browser Origin header from a non-SPA client | 9002326 | 9002326 | AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Request origin: 'https://lab.brambrinkmeier.com'. | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow) 3. [Microsoft Q&A: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type (1534740)](https://learn.microsoft.com/en-us/answers/questions/1534740/cross-origin-token-redemption-is-permitted-only-fo) 4. [Microsoft Q&A: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type (1608608)](https://learn.microsoft.com/en-us/answers/questions/1608608/cross-origin-token-redemption-is-permitted-only-fo) 5. [Ionic Forum: Capacitor MSAL Azure B2C - iOS not working AADSTS9002326](https://forum.ionicframework.com/t/capacitor-msal-azure-b2c-ios-not-working-aadsts9002326/240436) 6. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 7. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://docs.azure.cn/en-us/azure-monitor/reference/tables/AADServicePrincipalSignInLogs) ## Related codes [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS7000215](https://brambrinkmeier.com/entra/aadsts/7000215/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS9002327](https://brambrinkmeier.com/entra/aadsts/9002327/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS9002326: Cross-origin token request from a non-SPA app (fix)", https://brambrinkmeier.com/entra/aadsts/9002326/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/9002327/ # AADSTS9002327: SPA token redeemed without a browser Origin (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/9002327/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/9002327.json **Short answer:** AADSTS9002327 means a token request used an authorization code or refresh token issued to a single-page app, but the request had no Origin header, so it didn't come from a browser. Microsoft's error reference doesn't list it. A Q&A answerer links it to redemption from server-side code. Low attack value. Redeem in the browser, or register a Web platform. **Fix:** Developer: if the browser redeems tokens, let MSAL.js in the browser make the token call. If your server redeems the code or refreshes tokens, register a Web redirect URI and authenticate the server as a confidential client. Don't fake the `Origin` header in a backend. User: report the app name. | Field | Value | |---|---| | Code | AADSTS9002327 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS9002327 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS9002327 (checked 30 October 2026). The wording below comes from user reports. A user on Microsoft Q&A posted this token endpoint response (`400 Bad Request`, `invalid_request`): > AADSTS9002327: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests. The app was registered with the **Single-page application** platform and used the authorization code flow with PKCE. A Microsoft moderator answered that the error is thrown *"due to your token requests missing the Origin header"*, and gave two fixes: add the header, or change the redirect URI platform to **Web** or **Native/Desktop**. Another answerer, not marked as Microsoft staff, wrote: *"Usually, you get the AADSTS9002327 error when trying to exchange a refresh token from server-side code."*. The thread doesn't confirm which applied. Microsoft documents the rule, without the code number, in its authorization code flow reference: > Applications can't use a `spa` redirect URI with non-SPA flows, for example, native applications or client credential flows. To ensure security and best practices, the Microsoft identity platform returns an error if you attempt to use a `spa` redirect URI without an `Origin` header. Our reading: 9002327 is that error. A code or refresh token issued through a `spa` redirect URI can only be redeemed by a request that carries an `Origin` header, which is what a browser sends. It is the mirror of [9002326](https://brambrinkmeier.com/entra/aadsts/9002326/), where a request with an `Origin` header hits an app that isn't an SPA. ## Is it an attack? No. It is a mismatch between how the app is registered and where it redeems tokens. | Pattern | Likely meaning | |---|---| | A developer testing the token call in Postman or curl | No `Origin` header is sent. The SPA registration rejects it. Likely, but unconfirmed. | | An app that renders on the server (SSR, Blazor Server, MVC) registered as SPA | One Q&A answerer suggests this: the code is redeemed by server code, not the browser. | | A backend that takes the SPA's refresh token and refreshes it itself | One Q&A answerer calls this the usual cause. The refresh token stays bound to the browser. | | A sudden spike after a deployment | Probably token redemption moved from the browser to a backend or proxy (unconfirmed). | Our reading: the check is a defence. A code or refresh token issued to a browser app can't simply be redeemed from a script without the `Origin` header. Anyone can set that header in a script, though, so it is not a strong barrier. Don't treat it as one. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 9002327 is logged in, or whether it is logged at all. Check where it lands in your workspace: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "9002327" | summarize Rows = count() by SourceTable ``` If it does land in a user sign-in table, find the apps and the clients behind it. A server or tool user agent instead of a browser points at server-side redemption: ```kusto union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "9002327" | summarize Rows = count(), Users = dcount(UserPrincipalName), UserAgents = make_set(UserAgent, 10), IPs = make_set(IPAddress, 10) by AppDisplayName, AppId | sort by Rows desc ``` ## How do I fix AADSTS9002327? **For the user:** you can't fix this yourself. Report the app name to whoever runs it. **For developers:** 1. Decide where tokens should be redeemed. If the browser does it, use MSAL.js in the browser and let it make the token call. The browser sends the `Origin` header. 2. If your server redeems the code or refreshes tokens, the app isn't an SPA. Register a **Web** redirect URI and authenticate the server as a confidential client. That is one of the two fixes the Microsoft moderator gave. 3. The moderator's other fix was to add the `Origin` header. Our reading: fine for a test in Postman or curl. Don't ship a backend that fakes a browser header to get around the SPA rules. 4. Don't mix flows on one redirect URI. Microsoft: *"Applications can't use a `spa` redirect URI with non-SPA flows."* **For admins:** 1. Look at the app registration's **Authentication** page. Check which platform the failing redirect URI is under: **Single-page application**, **Web**, or **Mobile and desktop applications**. 2. If the app's backend does the redemption, move that redirect URI to **Web**, with the developer's agreement. Moving it changes how the app must authenticate. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. Lab-run rows naming this code (5; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | SPA-registered client redeems without an Origin header | 9002327 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-spa-41136574530'. Send | | 2026-10-30 | SPA-registered client redeems without an Origin header | 9002327 / 65001 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-spa-41139925607'. Send | | 2026-10-30 | SPA-registered client redeems without an Origin header | 9002327 / 65001 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-spa-41143330001'. Send | | 2026-10-31 | SPA-registered client redeems without an Origin header | 9002327 / 65001 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-spa-41146039117'. Send | | 2026-10-31 | SPA-registered client redeems without an Origin header | 9002327 / 65001 | 65001 | AADSTS65001: The user or administrator has not consented to use the application with ID '{app-id}' named 'lab-spa-41150019626'. Send | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Microsoft Q&A: AADSTS9002327: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests (1601797)](https://learn.microsoft.com/en-us/answers/questions/1601797/aadsts9002327-tokens-issued-for-the-single-page-ap) 3. [Microsoft identity platform and OAuth 2.0 authorization code flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS9002326](https://brambrinkmeier.com/entra/aadsts/9002326/), [AADSTS700054](https://brambrinkmeier.com/entra/aadsts/700054/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS7000218](https://brambrinkmeier.com/entra/aadsts/7000218/), [AADSTS700081](https://brambrinkmeier.com/entra/aadsts/700081/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS9002327: SPA token redeemed without a browser Origin (fix)", https://brambrinkmeier.com/entra/aadsts/9002327/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/9002331/ # AADSTS9002331: App is for personal Microsoft accounts only (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/9002331/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/9002331.json **Short answer:** AADSTS9002331 means the app is registered for personal Microsoft accounts only, but the sign-in didn't use the /consumers endpoint, or a work account tried to use it. Microsoft's error reference doesn't list it. Low attack value. Use the /consumers endpoint, or change the app's supported account types. **Fix:** Developer: for a personal-accounts-only app, sign in through `https://login.microsoftonline.com/consumers/`. If work or school accounts must sign in too, change Supported account types on the app registration. User: try your personal Microsoft account, or report it to the app's owner. | Field | Value | |---|---| | Code | AADSTS9002331 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS9002331 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS9002331 (checked 30 October 2026). The wording below comes from a user report on Microsoft Q&A. The user posted a screenshot; a Microsoft moderator quoted the text as: > AADSTS9002331: Application '...73f'(...Demo) is configured for use by Microsoft Account users only. Please use the /consumers endpoint to serve this request. The moderator's explanation: the app registration allows only personal Microsoft accounts (`PersonalMicrosoftAccount`), and the error happens when a user from a Microsoft Entra tenant or another identity provider tries to sign in. The fix given was to change the app's supported account types. The thread doesn't confirm the fix. The app setting behind it is **Supported account types**. Microsoft's signInAudience page maps **Personal Microsoft accounts only** to `signInAudience` value `PersonalMicrosoftAccount`. **A lab test on 30 October 2026 returned a different code for this case.** I registered an app with Supported account types set to personal Microsoft accounts only, then sent a password-grant request to my tenant's own endpoint. Entra answered with `AADSTS9002346`, not 9002331: > AADSTS9002346: Application ''() is configured for use by Microsoft Account users only. Please use the /consumers endpoint to serve this request. The wording is the same apart from the number. So on a current tenant this condition produces 9002346, while the user report above shows 9002331 for the same situation. Match on both if you are writing a rule, and see [9002346](https://brambrinkmeier.com/entra/aadsts/9002346/) for the lab-reproduced page. The endpoint matters too. Microsoft's OpenID Connect reference describes the `{tenant}` values in the sign-in URL: | Value | Microsoft's description | |---|---| | `common` | Users with both a personal Microsoft account and a work or school account from Microsoft Entra ID can sign in to the application. | | `organizations` | Only users with work or school accounts from Microsoft Entra ID can sign in to the application. | | `consumers` | Only users with a personal Microsoft account can sign in to the application. | | tenant ID or domain | Only users from a specific Microsoft Entra tenant [...] can sign in to the application. | Microsoft's error reference does list the reverse case, AADSTS9002332: *"Application '{principalId}'({principalName}) is configured for use by Microsoft Entra users only. Please do not use the /consumers endpoint to serve this request."* Our reading: 9002331 is its mirror. A personal-accounts-only app was called on an endpoint other than `/consumers`. ## Is it an attack? No. It is a mismatch between the app's supported account types and the sign-in endpoint or the account used. | Pattern | Likely meaning | |---|---| | A sample or tutorial app fails on first run | The app was registered as **Personal Microsoft accounts only** but the code uses a tenant ID, `/organizations` or `/common`. Our interpretation. | | A work account user can't sign in to an app that works for a personal account | The app was never meant for work accounts, or was registered with the wrong account type. | | A third-party product fails for your staff | The vendor's app is registered for personal accounts only. Only the vendor can change that. | ## How do I find it in my logs (KQL)? Microsoft doesn't document which table 9002331 is logged in. Our reading: an app registered for personal accounts only usually has no service principal in your tenant, and a request on `/consumers` or `/common` may never reach your tenant at all. Expect few or no rows. Check anyway: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "9002331" | summarize Rows = count(), Apps = make_set(AppId, 10) by SourceTable ``` ## How do I fix AADSTS9002331? **For the user:** if you have a personal Microsoft account (Outlook.com, Hotmail, Xbox), try that one. If the app should work with your work account, report it to the app's owner. **For developers:** 1. Decide who the app is for. Personal accounts only: sign in through `https://login.microsoftonline.com/consumers/`. That is what the error message asks for. 2. If work or school accounts must sign in too, change **Supported account types** on the app registration. The Microsoft moderator's fix was exactly this. Microsoft's signInAudience page lists the options and the validation rules that differ between them. 3. For both personal and work accounts, use `AzureADandPersonalMicrosoftAccount` and the `/common` endpoint. Microsoft notes that with `common` or `consumers` *"the consuming resource application must be configured to support such type of accounts"*. **For admins:** 1. If this is your own app registration, check **Supported account types** under the app's **Authentication** page, and agree the change with the developer. 2. If it is a vendor's app, you can't change it. Ask the vendor for a version registered for work accounts. ## Evidence Not in Microsoft's error reference and not reproduced in the lab; built from lab results, other Microsoft pages and user reports, which the page names. Lab-run rows naming this code (13; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Personal-accounts-only app on a tenant endpoint | 9002331 | 9002346 | AADSTS9002346: Application '{app-id}'(lab-msa-only-41136574530) is configured for use by Microsoft Account users only. Please use th | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Personal-accounts-only app on a tenant endpoint | 9002331 | 9002346 | AADSTS9002346: Application '{app-id}'(lab-msa-only-41139925607) is configured for use by Microsoft Account users only. Please use th | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-30 | Personal-accounts-only app on a tenant endpoint | 9002331 | 9002346 | AADSTS9002346: Application '{app-id}'(lab-msa-only-41143330001) is configured for use by Microsoft Account users only. Please use th | | 2026-10-30 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-31 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-31 | Personal-accounts-only app on a tenant endpoint | 9002331 | 9002346 | AADSTS9002346: Application '{app-id}'(lab-msa-only-41146039117) is configured for use by Microsoft Account users only. Please use th | | 2026-10-31 | Device code requested on /consumers by a work-account app | 90133 / 9002331 / 700016 | 700016 | AADSTS700016: Application with identifier '{app-id}' was not found in the directory '{tenant-id}'. This can | | 2026-10-31 | Personal-accounts-only app on a tenant endpoint | 9002331 | 9002346 | AADSTS9002346: Application '{app-id}'(lab-msa-only-41150019626) is configured for use by Microsoft Account users only. Please use th | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Microsoft Q&A: Access issue (1160493)](https://learn.microsoft.com/en-us/answers/questions/1160493/access-issue) 3. [OpenID Connect on the Microsoft identity platform](https://learn.microsoft.com/azure/active-directory/develop/v2-protocols-oidc) 4. [Validation differences by supported account types (signInAudience)](https://learn.microsoft.com/entra/identity-platform/supported-accounts-validation) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS50194](https://brambrinkmeier.com/entra/aadsts/50194/), [AADSTS9002346](https://brambrinkmeier.com/entra/aadsts/9002346/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS9002331: App is for personal Microsoft accounts only (fix)", https://brambrinkmeier.com/entra/aadsts/9002331/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/9002341/ # AADSTS9002341: User must allow Windows single sign-on (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/9002341/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/9002341.json **Short answer:** AADSTS9002341 means the user hasn't given permission for an app to use their Windows sign-in for single sign-on. Microsoft links it to the Windows SSO change in the European Economic Area, where Windows asks before reusing the Windows account in other apps. It has low attack value. Users accept the prompt; admins can auto-accept it on managed Windows 11 devices. **Fix:** User: when Windows asks to use your Windows account, choose to continue. Developer: catch it on the silent call and start an interactive sign-in. Admin: on managed Windows 11 24H2/25H2 devices, set `AutoAcceptSsoPermission` (DWORD) to `1` under `HKLM\SOFTWARE\Policies\Microsoft\Windows\AAD`. | Field | Value | |---|---| | Code | AADSTS9002341 | | Category | Consent and app permissions | | Type | Interrupt (an expected extra step, not a failure) | | Attack signal | Low: usually configuration or user error | | Where to look | `SigninLogs`, `AADNonInteractiveUserSignInLogs` | | In Microsoft's error reference | Yes | | Verification | documentation | | Last updated | 2026-10-30 | ## What does AADSTS9002341 mean? Microsoft's description: > V2Error: `invalid_grant` - The user is required to permit single sign-On (SSO). This error occurs when the user has not granted the necessary permissions for the application to perform SSO. The user should be redirected to the consent screen to grant the necessary permissions. Refer to [this announcement](https://techcommunity.microsoft.com/t5/windows-it-pro-blog/upcoming-changes-to-windows-single-sign-on/ba-p/4008151) for more information. The app tried to sign the user in with the credentials from their Windows sign-in. The user hadn't said yes to that, so the request failed with `invalid_grant`. The announcement Microsoft links to is the December 2023 Windows IT Pro post *Upcoming changes to Windows single sign-on*. It opens: *"Microsoft has been working to ensure compliance with the Digital Markets Act (DMA) in the European Economic Area (EEA)."* Microsoft's current Learn page on the change describes the behaviour. In the EEA, users *"are not automatically signed in to other Microsoft applications and services after signing in to Windows. Instead, Windows asks users whether they want to use the same credentials to sign in to additional apps or services."* The notice *"appears the first time a user uses an app that enables sign-in with a personal Microsoft account, or work or school Entra ID, after signing in to Windows. If the user chooses to use the same credentials they used to sign in to Windows, this notice will not appear again."* This is not the app consent you know from [65001](https://brambrinkmeier.com/entra/aadsts/65001/). Nobody grants API permissions here. The question is whether Windows may reuse the Windows account for single sign-on in this app. ## Is it an attack? No. It is a permission prompt on the user's own device, and the failure means no token was issued. There is no documented attack pattern. | Pattern | Likely meaning | |---|---| | 9002341 for users in the EEA on Windows, often the first time they open an app | The Windows SSO prompt hasn't been accepted yet. Benign. | | 9002341 followed by a success for the same user and app | The user accepted the prompt, or signed in another way. Working as designed. | | 9002341 repeating for one user and app, with no success | Our reading: the user declined the prompt (the screenshot on Microsoft's page shows a *Don't sign in* button) or the app doesn't send them to it. | | A drop in 9002341 after you deploy the admin setting | The auto-accept setting is in effect on those devices. | Exclude it from failure-rate dashboards and spray detections. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 9002341 is logged in. Check where it lands: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "9002341" | summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable ``` Which apps and operating systems hit it. `DeviceDetail` is `dynamic` in `SigninLogs` and `string` in `AADNonInteractiveUserSignInLogs`, so normalise it first: ```kusto union (SigninLogs | extend Dev = todynamic(DeviceDetail)), (AADNonInteractiveUserSignInLogs | extend Dev = todynamic(DeviceDetail)) | where TimeGenerated > ago(7d) | where ResultType == "9002341" | extend OS = tostring(Dev.operatingSystem) | summarize Rows = count(), Users = dcount(UserPrincipalName) by AppDisplayName, OS | sort by Users desc ``` Users who keep hitting it on the same app and don't succeed there after their first failure that day. These are the people to contact, or the devices to cover with the admin setting: ```kusto let prompts = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "9002341" | summarize Fails = count(), FirstFail = min(TimeGenerated) by UserPrincipalName, AppId, AppDisplayName; let successes = union SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(1d) | where ResultType == "0" | summarize LastSuccess = max(TimeGenerated) by UserPrincipalName, AppId; prompts | join kind=leftouter successes on UserPrincipalName, AppId | where isnull(LastSuccess) or LastSuccess < FirstFail | project UserPrincipalName, AppDisplayName, Fails, FirstFail | sort by Fails desc ``` The threshold is up to you; start with users who have more than a handful of `Fails`. `ResultType` is a **string** column, so compare it with `"9002341"`, not `9002341`. ## How do I fix AADSTS9002341? **For the user:** when Windows asks whether to use your Windows account to sign in to the app, choose to continue. Microsoft says the notice then *"will not appear again"* for that app. **For developers:** Microsoft's description says *"The user should be redirected to the consent screen to grant the necessary permissions."* Treat 9002341 like other interaction-required errors: catch it on the silent call and start an interactive sign-in, so the user sees the prompt. **For admins:** 1. On managed Windows devices you can accept the prompt for your users. Microsoft documents a registry policy: path `HKLM\SOFTWARE\Policies\Microsoft\Windows\AAD`, value `AutoAcceptSsoPermission` (DWORD) = `1`. 2. Requirements, per Microsoft: Windows 11, version 24H2 or 25H2, with the July 2026 security update (KB5101650) or later. It *"Applies only to Windows managed enterprise devices with Microsoft Entra ID accounts."* 3. Deploy it with Group Policy, Intune or another MDM, Configuration Manager, or *"Any management tool that supports registry policy deployment."* 4. Personal Microsoft accounts and unmanaged devices have no admin control. Those users still see the prompt. 5. Run the third query again after the rollout and check that the remaining users are on unmanaged or older devices. ## Evidence Not reproduced in the lab yet; the page is based on Microsoft's documentation. ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Admin control for SSO prompts in Windows](https://learn.microsoft.com/en-us/entra/identity/devices/sso-admin-control) 3. [Upcoming changes to Windows single sign-on (Windows IT Pro Blog)](https://techcommunity.microsoft.com/blog/windows-itpro-blog/upcoming-changes-to-windows-single-sign-on/4008151) 4. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 5. [AADNonInteractiveUserSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadnoninteractiveusersigninlogs) ## Related codes [AADSTS65001](https://brambrinkmeier.com/entra/aadsts/65001/), [AADSTS50058](https://brambrinkmeier.com/entra/aadsts/50058/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS9002341: User must allow Windows single sign-on (fix)", https://brambrinkmeier.com/entra/aadsts/9002341/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/9002346/ # AADSTS9002346: App is for personal Microsoft accounts only (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/9002346/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/9002346.json **Short answer:** AADSTS9002346 means the app registration is set to personal Microsoft accounts only, and the request went to a tenant endpoint instead of /consumers. Microsoft's error reference doesn't list it. It is a configuration error with low attack value. Either call /consumers, or change Supported account types on the app registration. **Fix:** Developer: for a personal-accounts-only app, send the request to `https://login.microsoftonline.com/consumers/`. If work or school accounts must sign in too, change Supported account types on the app registration. User: try your personal Microsoft account. | Field | Value | |---|---| | Code | AADSTS9002346 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS9002346 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS9002346 (checked 30 October 2026). We found no other Microsoft page that names it. The wording below is from a lab run: > AADSTS9002346: Application '\'(\) is configured for use by Microsoft Account users only. Please use th... The lab records only the first line of `error_description`, cut at about 160 characters. The sentence completes as *"Please use the /consumers endpoint to serve this request"*, which is how the same message appears in a user report for the near-identical code [9002331](https://brambrinkmeier.com/entra/aadsts/9002331/). The setting behind it is **Supported account types** on the app registration. Microsoft's signInAudience page maps the portal choices to manifest values: | Supported account types | `signInAudience` | |---|---| | Accounts in this organizational directory only (Single tenant) | `AzureADMyOrg` | | Accounts in any organizational directory (Any Microsoft Entra directory - Multitenant) | `AzureADMultipleOrgs` | | Accounts in any organizational directory ... and personal Microsoft accounts (such as Skype, Xbox) | `AzureADandPersonalMicrosoftAccount` | | Personal Microsoft accounts only | `PersonalMicrosoftAccount` | An app at `PersonalMicrosoftAccount` exists only for consumer accounts, and consumer accounts sign in through `/consumers`. Microsoft's OpenID Connect reference describes the endpoint values: | Value | Microsoft's description | |---|---| | `common` | Users with both a personal Microsoft account and a work or school account from Microsoft Entra ID can sign in to the application. | | `organizations` | Only users with work or school accounts from Microsoft Entra ID can sign in to the application. | | `consumers` | Only users with a personal Microsoft account can sign in to the application. | | Directory (tenant) ID or domain | Only users from a specific Microsoft Entra tenant ... can sign in to the application. | So the request named a tenant that the app does not serve. Microsoft's reference does list the mirror case, **AADSTS9002332**: *"Application '{principalId}'({principalName}) is configured for use by Microsoft Entra users only. Please do not use the /consumers endpoint to serve this request."* 9002346 is the same check in the other direction. ### 9002346 and 9002331 [9002331](https://brambrinkmeier.com/entra/aadsts/9002331/) carries the same sentence with a different number. A Microsoft Q&A thread quotes it as *"AADSTS9002331: Application '...73f'(...Demo) is configured for use by Microsoft Account users only. Please use the /consumers endpoint to serve this request."*, and a Microsoft moderator answers: *"From your error message, it looks like your App Registration is set for users to sign-in using their `PersonalMicrosoftAccount` only."* On a current tenant, the lab run below produced 9002346 for that condition, not 9002331. We can't tell from one tenant whether 9002331 is older, path-specific or flow-specific, so treat them as one condition and match on both in a detection rule. ## Reproduced in the lab On 30 October 2026 an automated lab run registered an app with **Supported account types** set to personal Microsoft accounts only, then sent a password-grant (ROPC) token request to the lab tenant's own endpoint, with a user from that tenant. Entra returned `AADSTS9002346`: > AADSTS9002346: Application '\'(\) is configured for use by Microsoft Account users only. Please use th... Control requests in the same run, using an ordinary single-tenant app on the same endpoint with the same user, reached the credential check and returned either a token or a credential error. So 9002346 is about the app's supported account types and the endpoint, not about the user or the password. No sign-in log row was captured. See [how pages are checked](https://brambrinkmeier.com/methodology/). In the lab tenant's sign-in logs the row appears under **User sign-ins (interactive)**, Status **Failure**, Conditional Access **Not Applied**, with the Application column naming the personal-accounts-only app. ## Is it an attack? No. The app's supported account types and the endpoint the code calls disagree. | Pattern | Likely meaning | |---|---| | A sample or tutorial app fails on the first run | Registered as **Personal Microsoft accounts only** while the code uses a tenant ID, `/organizations` or `/common`. | | Work account users can't sign in to an app that works with a personal account | The app was never meant for work accounts, or the account type was set wrongly at registration. | | A third-party product fails for all your staff | The vendor's app registration is consumer-only. Only the vendor can change that. | | It appears right after someone edited the app registration | **Supported account types** was narrowed to personal accounts only. Check the audit log. | ## How do I find it in my logs (KQL)? Which sign-in table 9002346 lands in is undocumented, and our reading is that most of these never reach your tenant's logs at all: a consumer-only app usually has no service principal in your tenant, and the refusal happens at the endpoint. Expect few or no rows, and check with a union rather than guessing one table: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType in ("9002346", "9002331") or ResultSignature in ("9002346", "9002331") | summarize Rows = count(), Apps = make_set(AppId, 10), LastSeen = max(TimeGenerated) by SourceTable, ResultType ``` If you do get rows, the faster question is which account types your own app registrations use. That is a Graph or PowerShell query against the directory, not a log query: ```powershell Connect-MgGraph -Scopes "Application.Read.All" Get-MgApplication -All | Where-Object { $_.SignInAudience -eq "PersonalMicrosoftAccount" } | Select-Object DisplayName, AppId, SignInAudience ``` ## How do I fix AADSTS9002346? **For the user:** if you have a personal Microsoft account (Outlook.com, Hotmail, Xbox), try signing in with that one. If the app is meant for your work account, report it to whoever owns the app. **For developers:** 1. Decide who the app is for. Personal accounts only: send the request to `https://login.microsoftonline.com/consumers/`, which is what the error message asks for. 2. If work or school accounts must sign in too, change **Supported account types** on the app registration. For both kinds of account, use `AzureADandPersonalMicrosoftAccount` and the `/common` endpoint. 3. Don't hardcode a tenant ID in an app registered for personal accounts only. The two settings contradict each other. **For admins:** 1. For your own app registration, check **Supported account types** on the app's **Authentication** page, and agree any change with the developer. Microsoft's signInAudience page lists the validation rules that differ between the account types, so a change can also require edits elsewhere in the registration. 2. For a vendor's app, you cannot change it. Ask the vendor for a registration that supports work accounts. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Password-grant (ROPC) token request against a lab tenant; scenario: Personal-accounts-only app on a tenant endpoint). First line returned: > AADSTS9002346: Application '{app-id}'(lab-msa-only-41136574530) is configured for use by Microsoft Account users only. Please use th Sign-in log row read: 2026-10-31. Lab-run rows naming this code (5; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Personal-accounts-only app on a tenant endpoint | 9002331 | 9002346 | AADSTS9002346: Application '{app-id}'(lab-msa-only-41136574530) is configured for use by Microsoft Account users only. Please use th | | 2026-10-30 | Personal-accounts-only app on a tenant endpoint | 9002331 | 9002346 | AADSTS9002346: Application '{app-id}'(lab-msa-only-41139925607) is configured for use by Microsoft Account users only. Please use th | | 2026-10-30 | Personal-accounts-only app on a tenant endpoint | 9002331 | 9002346 | AADSTS9002346: Application '{app-id}'(lab-msa-only-41143330001) is configured for use by Microsoft Account users only. Please use th | | 2026-10-31 | Personal-accounts-only app on a tenant endpoint | 9002331 | 9002346 | AADSTS9002346: Application '{app-id}'(lab-msa-only-41146039117) is configured for use by Microsoft Account users only. Please use th | | 2026-10-31 | Personal-accounts-only app on a tenant endpoint | 9002331 | 9002346 | AADSTS9002346: Application '{app-id}'(lab-msa-only-41150019626) is configured for use by Microsoft Account users only. Please use th | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) 2. [Validation differences by supported account types (signInAudience)](https://learn.microsoft.com/en-us/entra/identity-platform/supported-accounts-validation) 3. [OpenID Connect on the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc) 4. [Microsoft Q&A: Access issue (1160493)](https://learn.microsoft.com/en-us/answers/questions/1160493/access-issue) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) ## Related codes [AADSTS9002331](https://brambrinkmeier.com/entra/aadsts/9002331/), [AADSTS50020](https://brambrinkmeier.com/entra/aadsts/50020/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/), [AADSTS90002](https://brambrinkmeier.com/entra/aadsts/90002/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS9002346: App is for personal Microsoft accounts only (fix)", https://brambrinkmeier.com/entra/aadsts/9002346/ (CC BY 4.0), last updated 2026-10-30. ------------------------------------------------------------------------------ Page: https://brambrinkmeier.com/entra/aadsts/9010010/ # AADSTS9010010: Resource parameter doesn't match the requested scopes (fix) Canonical: https://brambrinkmeier.com/entra/aadsts/9010010/ By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/9010010.json **Short answer:** AADSTS9010010 means a token request carried a resource parameter that doesn't match the resource named in its scopes. Microsoft documents it for MCP clients: the resource value must exactly match the Application ID URI, and the scopes must belong to that same app. A trailing slash is a common cause. It is a client configuration error with low attack value. **Fix:** Developer: send `resource` exactly as the Application ID URI (no trailing slash, same case and path), and keep every scope on that API. If you don't need RFC 8707, drop `resource` and name the API only in `scope`. MCP server owner: use v2 access tokens and publish the same value in your metadata. | Field | Value | |---|---| | Code | AADSTS9010010 | | Category | App configuration | | Type | Configuration error | | Attack signal | Low: usually configuration or user error | | In Microsoft's error reference | No (checked 2026-10-30) | | Verification | lab-reproduced (2026-10-30) | | Last updated | 2026-10-30 | ## What does AADSTS9010010 mean? Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS9010010 (checked 30 October 2026). My lab tenant returned this message for a client-credentials token request that carried both `scope=https://graph.microsoft.com/.default` and `resource=https://management.azure.com/`: > AADSTS9010010: The resource parameter provided in the request doesn't match with the requested scopes. Microsoft does explain the code, on its page about securing an MCP server with Entra ID: > `AADSTS9010010` means the **Application ID URI configured on your app registration doesn't exactly match the value of the `resource` parameter** in the client's OAuth request. The same page gives a second cause: *"This error also occurs when the client sends a scope that's defined on a different app registration than the one referenced by the `resource` parameter. Microsoft Entra ID resolves the `resource` and the scope to the same resource app; if they point at different app registrations, the request fails."* That second cause is what the lab request did: the scope names Microsoft Graph, the resource names Azure Resource Manager. Background. On the v2.0 endpoint the resource is normally named inside the scope. Microsoft's scopes page: *"Using `scope={resource-identifier}/.default` is functionally the same as `resource={resource-identifier}` on the v1.0 endpoint."* The `resource` parameter comes back through RFC 8707 (Resource Indicators), which the MCP authorization spec requires. Microsoft's MCP page: *"The MCP specification requires the client to identify the protected resource it wants a token for by sending the `resource` parameter (from RFC 8707) in its token request."* So a request now carries the resource twice, and the two must agree. The match is exact. Microsoft: *"The `resource` value the client sends must match the Application ID URI character for character, including the scheme (`https://`), casing of the host, and path. A trailing slash is a common culprit: because an Application ID URI can't end with a slash, a client that sends `resource=https://mcp.contoso.com/` never matches the registered `https://mcp.contoso.com`."* ## Reproduced in the lab On 30 October 2026 an automated lab run sent a client-credentials request to the token endpoint with `scope=https://graph.microsoft.com/.default` and `resource=https://management.azure.com/`. Entra returned `AADSTS9010010` with this first line: > AADSTS9010010: The resource parameter provided in the request doesn't match with the requested scopes. That confirms the code and its wording at the token endpoint for an app (not a user) request. It lands in **`AADServicePrincipalSignInLogs`** for an app-only request: one row, Failure, client credential type "federatedIdentityCredential", resource Microsoft Graph. The KQL below was run on these rows ([how](https://brambrinkmeier.com/methodology/)). Both queries found the row (the second with its app ID placeholder replaced). ## Is it an attack? No. It is a mismatch in how the client builds its token request. No token is issued. | Pattern | Likely meaning | |---|---| | An MCP client (Claude Code, an IDE, an agent) fails to connect to an Entra-protected MCP server | The client sends `resource` with a trailing slash, or a URL that differs from the Application ID URI. Users report exactly this in [claude-code issue 52871](https://github.com/anthropics/claude-code/issues/52871), where `resource=https://mcp.businesscentral.dynamics.com/` was sent while the server's metadata declared it without the slash. | | A script or daemon sends `resource` and `scope` for two different APIs | The scope belongs to another app registration, as in the lab request. | | A broker or identity provider in front of Entra forwards `resource` with only OIDC scopes (`openid profile`) | Users report this with Auth0 federated to Entra in the same GitHub issue. Our reading: no resource-prefixed scope exists to match. | | Your own MCP server app is still on v1 access tokens | Microsoft: if `requestedAccessTokenVersion` isn't `2`, *"you can't register an HTTPS Application ID URI that matches your MCP server URL, so the `resource` value can never match."* | Our reading: the request fails before a token is issued, and only the app's own owner can make it match. There is nothing an attacker gains from triggering it. ## How do I find it in my logs (KQL)? Microsoft doesn't document which sign-in table 9010010 is logged in. Our reading: user-delegated requests (MCP clients signing in a user) would land in `SigninLogs` or `AADNonInteractiveUserSignInLogs`, and app-only requests like the lab one in `AADServicePrincipalSignInLogs`. That is not verified. Check all three: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where ResultType == "9010010" | summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, AppId, ResourceDisplayName | sort by Rows desc ``` To fix the request you need the right resource. For an app that fails with 9010010, see which resources it does get tokens for: ```kusto union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs | where TimeGenerated > ago(30d) | where AppId == "" | summarize Successes = countif(ResultType == "0"), Failures9010010 = countif(ResultType == "9010010") by SourceTable, ResourceDisplayName, ResourceIdentity | sort by Failures9010010 desc ``` A resource with failures and no successes is the one whose `resource` value or scope is wrong. Both queries are starting points; adjust the time window to your retention. ## How do I fix AADSTS9010010? **For the user:** you can't fix this yourself. Report the app or MCP server name to whoever set it up, and include the full error. **For developers (client side):** 1. If you talk to the v2.0 endpoint and don't need RFC 8707, drop `resource` and name the API only in `scope`, for example `scope=https://graph.microsoft.com/.default`. Microsoft's scopes page says the two are functionally the same. 2. If you must send `resource` (MCP clients do), send it verbatim from the server's protected resource metadata. Don't normalise it; the reporter of [claude-code issue 52871](https://github.com/anthropics/claude-code/issues/52871) suspects that round-tripping it through a URL parser added the trailing slash. Nobody in the thread confirmed that. 3. Make every scope in the request belong to the same API as `resource`. Remove scopes from other APIs and request them in a separate token request. **For developers (MCP server side), from Microsoft's MCP page:** 1. Set the app registration to v2 access tokens (`requestedAccessTokenVersion` = `2`). 2. Set the Application ID URI to the exact canonical URL of your MCP server, with no trailing slash. 3. Publish that same value as `resource` in your protected resource metadata, so clients send what Entra expects. **For admins:** compare the failing app's `resource` value with the Application ID URI of the API's app registration. If they differ by a slash, a case or a path, that is the cause. ## Evidence Reproduced in a lab tenant on 2026-10-30 (Client-credentials token request against a lab tenant; scenario: Both scope and resource sent). First line returned: > AADSTS9010010: The resource parameter provided in the request doesn't match with the requested scopes. Sign-in log row read: 2026-10-30. KQL run against the exported lab rows: 2026-10-30. Lab-run rows naming this code (8; full list at https://brambrinkmeier.com/lab-runs.json): | Date | Scenario | Expected | Got | Message (first line) | |---|---|---|---|---| | 2026-10-30 | Both scope and resource sent | 9010010 | 9010010 | AADSTS9010010: The resource parameter provided in the request doesn't match with the requested scopes. | | 2026-10-30 | Both scope and resource sent | 9010010 | 9010010 | AADSTS9010010: The resource parameter provided in the request doesn't match with the requested scopes. | | 2026-10-30 | Both scope and resource sent | 9010010 | 9010010 | AADSTS9010010: The resource parameter provided in the request doesn't match with the requested scopes. | | 2026-10-30 | Both scope and resource sent | 9010010 | success | | | 2026-10-30 | Both scope and resource sent | 9010010 | success | | | 2026-10-30 | Both scope and resource sent | 9010010 | 9010010 | AADSTS9010010: The resource parameter provided in the request doesn't match with the requested scopes. | | 2026-10-31 | Both scope and resource sent | 9010010 | 9010010 | AADSTS9010010: The resource parameter provided in the request doesn't match with the requested scopes. | | 2026-10-31 | Both scope and resource sent | 9010010 | success | | ## Sources 1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) 2. [Secure a Model Context Protocol (MCP) server with Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/agent-id/secure-mcp-server-with-entra-id) 3. [Scopes and permissions in the Microsoft identity platform](https://learn.microsoft.com/entra/identity-platform/scopes-oidc) 4. [anthropics/claude-code issue 52871 (AADSTS9010010 with MCP OAuth)](https://github.com/anthropics/claude-code/issues/52871) 5. [SigninLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs) 6. [AADServicePrincipalSignInLogs table reference (Azure Monitor)](https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs) ## Related codes [AADSTS500011](https://brambrinkmeier.com/entra/aadsts/500011/), [AADSTS9002313](https://brambrinkmeier.com/entra/aadsts/9002313/), [AADSTS700016](https://brambrinkmeier.com/entra/aadsts/700016/) ## License and citation CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change. Cite as: Bram Brinkmeier, "AADSTS9010010: Resource parameter doesn't match the requested scopes (fix)", https://brambrinkmeier.com/entra/aadsts/9010010/ (CC BY 4.0), last updated 2026-10-30.