{
  "schemaVersion": "1.0",
  "code": "9002341",
  "name": null,
  "title": "AADSTS9002341: User must allow Windows single sign-on (fix)",
  "url": "https://brambrinkmeier.com/entra/aadsts/9002341/",
  "alternates": {
    "markdown": "https://brambrinkmeier.com/entra/aadsts/9002341.md",
    "json": "https://brambrinkmeier.com/api/aadsts/9002341.json",
    "html": "https://brambrinkmeier.com/entra/aadsts/9002341/"
  },
  "description": "AADSTS9002341: the user hasn't allowed an app to use their Windows sign-in for SSO (EEA consent prompt). Low attack value; how to auto-accept. KQL.",
  "summary": "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.",
  "inMicrosoftReference": true,
  "unlistedChecked": null,
  "meaningText": "Microsoft's description:\n\n> 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.\n\nThe 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`.\n\nThe 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).\"*\n\nMicrosoft'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.\"*\n\nThis 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.",
  "sections": [
    {
      "heading": "What does AADSTS9002341 mean?",
      "text": "Microsoft's description:\n\n> 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.\n\nThe 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`.\n\nThe 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).\"*\n\nMicrosoft'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.\"*\n\nThis 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."
    },
    {
      "heading": "Is it an attack?",
      "text": "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.\n\n| Pattern | Likely meaning |\n|---|---|\n| 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. |\n| 9002341 followed by a success for the same user and app | The user accepted the prompt, or signed in another way. Working as designed. |\n| 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. |\n| A drop in 9002341 after you deploy the admin setting | The auto-accept setting is in effect on those devices. |\n\nExclude it from failure-rate dashboards and spray detections."
    },
    {
      "heading": "How do I find it in my logs (KQL)?",
      "text": "Microsoft doesn't document which sign-in table 9002341 is logged in. Check where it lands:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"9002341\"\n| summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable\n```\n\nWhich apps and operating systems hit it. `DeviceDetail` is `dynamic` in `SigninLogs` and `string` in `AADNonInteractiveUserSignInLogs`, so normalise it first:\n\n```kusto\nunion\n    (SigninLogs | extend Dev = todynamic(DeviceDetail)),\n    (AADNonInteractiveUserSignInLogs | extend Dev = todynamic(DeviceDetail))\n| where TimeGenerated > ago(7d)\n| where ResultType == \"9002341\"\n| extend OS = tostring(Dev.operatingSystem)\n| summarize Rows = count(), Users = dcount(UserPrincipalName) by AppDisplayName, OS\n| sort by Users desc\n```\n\nUsers 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:\n\n```kusto\nlet prompts =\n    union SigninLogs, AADNonInteractiveUserSignInLogs\n    | where TimeGenerated > ago(1d)\n    | where ResultType == \"9002341\"\n    | summarize Fails = count(), FirstFail = min(TimeGenerated) by UserPrincipalName, AppId, AppDisplayName;\nlet successes =\n    union SigninLogs, AADNonInteractiveUserSignInLogs\n    | where TimeGenerated > ago(1d)\n    | where ResultType == \"0\"\n    | summarize LastSuccess = max(TimeGenerated) by UserPrincipalName, AppId;\nprompts\n| join kind=leftouter successes on UserPrincipalName, AppId\n| where isnull(LastSuccess) or LastSuccess < FirstFail\n| project UserPrincipalName, AppDisplayName, Fails, FirstFail\n| sort by Fails desc\n```\n\nThe 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`."
    },
    {
      "heading": "How do I fix AADSTS9002341?",
      "text": "**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.\n\n**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.\n\n**For admins:**\n1. 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`.\n2. 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.\"*\n3. Deploy it with Group Policy, Intune or another MDM, Configuration Manager, or *\"Any management tool that supports registry policy deployment.\"*\n4. Personal Microsoft accounts and unmanaged devices have no admin control. Those users still see the prompt.\n5. Run the third query again after the rollout and check that the remaining users are on unmanaged or older devices."
    }
  ],
  "microsoftWording": {
    "text": "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.",
    "source": "Microsoft's error code reference, as quoted on the page",
    "sourceUrl": "https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes"
  },
  "securityReading": {
    "category": {
      "id": "consent",
      "label": "Consent and app permissions"
    },
    "kind": {
      "id": "interrupt",
      "label": "Interrupt (an expected extra step, not a failure)"
    },
    "attackSignal": {
      "level": "low",
      "label": "Low: usually configuration or user error"
    },
    "mitre": [],
    "tables": [
      "SigninLogs",
      "AADNonInteractiveUserSignInLogs"
    ],
    "isItAnAttack": "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.\n\n| Pattern | Likely meaning |\n|---|---|\n| 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. |\n| 9002341 followed by a success for the same user and app | The user accepted the prompt, or signed in another way. Working as designed. |\n| 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. |\n| A drop in 9002341 after you deploy the admin setting | The auto-accept setting is in effect on those devices. |\n\nExclude it from failure-rate dashboards and spray detections.",
    "conditionalAccess": null
  },
  "kql": [
    {
      "title": null,
      "leadIn": "Microsoft doesn't document which sign-in table 9002341 is logged in. Check where it lands:",
      "query": "union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"9002341\"\n| summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable"
    },
    {
      "title": null,
      "leadIn": "Which apps and operating systems hit it. `DeviceDetail` is `dynamic` in `SigninLogs` and `string` in `AADNonInteractiveUserSignInLogs`, so normalise it first:",
      "query": "union\n    (SigninLogs | extend Dev = todynamic(DeviceDetail)),\n    (AADNonInteractiveUserSignInLogs | extend Dev = todynamic(DeviceDetail))\n| where TimeGenerated > ago(7d)\n| where ResultType == \"9002341\"\n| extend OS = tostring(Dev.operatingSystem)\n| summarize Rows = count(), Users = dcount(UserPrincipalName) by AppDisplayName, OS\n| sort by Users desc"
    },
    {
      "title": null,
      "leadIn": "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:",
      "query": "let prompts =\n    union SigninLogs, AADNonInteractiveUserSignInLogs\n    | where TimeGenerated > ago(1d)\n    | where ResultType == \"9002341\"\n    | summarize Fails = count(), FirstFail = min(TimeGenerated) by UserPrincipalName, AppId, AppDisplayName;\nlet successes =\n    union SigninLogs, AADNonInteractiveUserSignInLogs\n    | where TimeGenerated > ago(1d)\n    | where ResultType == \"0\"\n    | summarize LastSuccess = max(TimeGenerated) by UserPrincipalName, AppId;\nprompts\n| join kind=leftouter successes on UserPrincipalName, AppId\n| where isnull(LastSuccess) or LastSuccess < FirstFail\n| project UserPrincipalName, AppDisplayName, Fails, FirstFail\n| sort by Fails desc"
    }
  ],
  "kqlSectionText": "Microsoft doesn't document which sign-in table 9002341 is logged in. Check where it lands:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"9002341\"\n| summarize Rows = count(), Users = dcount(UserPrincipalName) by SourceTable\n```\n\nWhich apps and operating systems hit it. `DeviceDetail` is `dynamic` in `SigninLogs` and `string` in `AADNonInteractiveUserSignInLogs`, so normalise it first:\n\n```kusto\nunion\n    (SigninLogs | extend Dev = todynamic(DeviceDetail)),\n    (AADNonInteractiveUserSignInLogs | extend Dev = todynamic(DeviceDetail))\n| where TimeGenerated > ago(7d)\n| where ResultType == \"9002341\"\n| extend OS = tostring(Dev.operatingSystem)\n| summarize Rows = count(), Users = dcount(UserPrincipalName) by AppDisplayName, OS\n| sort by Users desc\n```\n\nUsers 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:\n\n```kusto\nlet prompts =\n    union SigninLogs, AADNonInteractiveUserSignInLogs\n    | where TimeGenerated > ago(1d)\n    | where ResultType == \"9002341\"\n    | summarize Fails = count(), FirstFail = min(TimeGenerated) by UserPrincipalName, AppId, AppDisplayName;\nlet successes =\n    union SigninLogs, AADNonInteractiveUserSignInLogs\n    | where TimeGenerated > ago(1d)\n    | where ResultType == \"0\"\n    | summarize LastSuccess = max(TimeGenerated) by UserPrincipalName, AppId;\nprompts\n| join kind=leftouter successes on UserPrincipalName, AppId\n| where isnull(LastSuccess) or LastSuccess < FirstFail\n| project UserPrincipalName, AppDisplayName, Fails, FirstFail\n| sort by Fails desc\n```\n\nThe 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`.",
  "fix": {
    "short": "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`.",
    "steps": "**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.\n\n**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.\n\n**For admins:**\n1. 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`.\n2. 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.\"*\n3. Deploy it with Group Policy, Intune or another MDM, Configuration Manager, or *\"Any management tool that supports registry policy deployment.\"*\n4. Personal Microsoft accounts and unmanaged devices have no admin control. Those users still see the prompt.\n5. Run the third query again after the rollout and check that the remaining users are on unmanaged or older devices."
  },
  "labReproduced": null,
  "labSectionText": null,
  "labRuns": [],
  "verification": "documentation",
  "related": [
    "65001",
    "50058"
  ],
  "coveredBy": [],
  "sources": [
    {
      "title": "Microsoft Entra authentication and authorization error codes",
      "url": "https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes"
    },
    {
      "title": "Admin control for SSO prompts in Windows",
      "url": "https://learn.microsoft.com/en-us/entra/identity/devices/sso-admin-control"
    },
    {
      "title": "Upcoming changes to Windows single sign-on (Windows IT Pro Blog)",
      "url": "https://techcommunity.microsoft.com/blog/windows-itpro-blog/upcoming-changes-to-windows-single-sign-on/4008151"
    },
    {
      "title": "SigninLogs table reference (Azure Monitor)",
      "url": "https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs"
    },
    {
      "title": "AADNonInteractiveUserSignInLogs table reference (Azure Monitor)",
      "url": "https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadnoninteractiveusersigninlogs"
    }
  ],
  "published": "2026-10-30",
  "lastUpdated": "2026-10-30",
  "lastVerified": null,
  "license": "CC BY 4.0",
  "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
  "licenseNote": "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.",
  "attribution": "Bram Brinkmeier, \"AADSTS9002341: User must allow Windows single sign-on (fix)\", https://brambrinkmeier.com/entra/aadsts/9002341/ (CC BY 4.0)",
  "microsoftErrorLookup": "https://login.microsoftonline.com/error?code=9002341"
}
