{
  "schemaVersion": "1.0",
  "code": "901002",
  "name": null,
  "title": "AADSTS901002 fix: resource parameter sent to v2.0 endpoint",
  "url": "https://brambrinkmeier.com/entra/aadsts/901002/",
  "alternates": {
    "markdown": "https://brambrinkmeier.com/entra/aadsts/901002.md",
    "json": "https://brambrinkmeier.com/api/aadsts/901002.json",
    "html": "https://brambrinkmeier.com/entra/aadsts/901002/"
  },
  "description": "AADSTS901002: an app sent the v1.0 resource parameter to the v2.0 endpoint. Use scope=<API>/.default or the v1.0 URLs. KQL included.",
  "summary": "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=<API>` with `scope=<API>/.default`, or point the app at the v1.0 endpoints it was built for.",
  "inMicrosoftReference": true,
  "unlistedChecked": null,
  "meaningText": "Microsoft's description:\n\n> AADSTS901002: The 'resource' request parameter isn't supported.\n\nThe 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.\n\nThe 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.\"*\n\nThere 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.\n\nNot 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.",
  "sections": [
    {
      "heading": "What does AADSTS901002 mean?",
      "text": "Microsoft's description:\n\n> AADSTS901002: The 'resource' request parameter isn't supported.\n\nThe 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.\n\nThe 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.\"*\n\nThere 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.\n\nNot 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."
    },
    {
      "heading": "Is it an attack?",
      "text": "No. It is a configuration mismatch between an app and the endpoint it was pointed at. The request fails and no token is issued.\n\n| Pattern | Likely meaning |\n|---|---|\n| 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`. |\n| A home-built app after someone \"upgraded\" its URLs to v2.0 | The URLs changed but the request parameters didn't. |\n| A script that mixes v1.0 examples with a v2.0 token URL | Same mismatch, by hand. |\n\nExclude it from failure-based attack detections."
    },
    {
      "heading": "How do I find it in my logs (KQL)?",
      "text": "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:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"901002\"\n| summarize Rows = count(), Apps = dcount(AppId) by SourceTable\n```\n\nWhich apps send the v1.0 parameter, and since when:\n\n```kusto\nunion SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(14d)\n| where ResultType == \"901002\"\n| summarize Rows = count(), Users = dcount(UserPrincipalName),\n            FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated),\n            IPs = make_set(IPAddress, 5)\n          by AppDisplayName, AppId, ServicePrincipalName\n| sort by Rows desc\n```\n\n`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."
    },
    {
      "heading": "How do I fix AADSTS901002?",
      "text": "**For the user:** you can't fix this yourself. Report it to IT, with the name of the app.\n\n**For developers:**\n1. Remove `resource` from requests to `/oauth2/v2.0/authorize` and `/oauth2/v2.0/token`.\n2. 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`.\n3. 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`\"*.\n\n**For admins of a third-party product:**\n1. Check which endpoint the product expects. If its documentation asks for a \"resource\" or \"resource URI\", it is built for v1.0.\n2. 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.\n3. 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."
    }
  ],
  "microsoftWording": {
    "text": "AADSTS901002: The 'resource' request parameter isn't supported.",
    "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": "app-config",
      "label": "App configuration"
    },
    "kind": {
      "id": "config",
      "label": "Configuration error"
    },
    "attackSignal": {
      "level": "low",
      "label": "Low: usually configuration or user error"
    },
    "mitre": [],
    "tables": [],
    "isItAnAttack": "No. It is a configuration mismatch between an app and the endpoint it was pointed at. The request fails and no token is issued.\n\n| Pattern | Likely meaning |\n|---|---|\n| 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`. |\n| A home-built app after someone \"upgraded\" its URLs to v2.0 | The URLs changed but the request parameters didn't. |\n| A script that mixes v1.0 examples with a v2.0 token URL | Same mismatch, by hand. |\n\nExclude it from failure-based attack detections.",
    "conditionalAccess": null
  },
  "kql": [
    {
      "title": null,
      "leadIn": "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:",
      "query": "union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"901002\"\n| summarize Rows = count(), Apps = dcount(AppId) by SourceTable"
    },
    {
      "title": null,
      "leadIn": "Which apps send the v1.0 parameter, and since when:",
      "query": "union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(14d)\n| where ResultType == \"901002\"\n| summarize Rows = count(), Users = dcount(UserPrincipalName),\n            FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated),\n            IPs = make_set(IPAddress, 5)\n          by AppDisplayName, AppId, ServicePrincipalName\n| sort by Rows desc"
    }
  ],
  "kqlSectionText": "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:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"901002\"\n| summarize Rows = count(), Apps = dcount(AppId) by SourceTable\n```\n\nWhich apps send the v1.0 parameter, and since when:\n\n```kusto\nunion SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(14d)\n| where ResultType == \"901002\"\n| summarize Rows = count(), Users = dcount(UserPrincipalName),\n            FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated),\n            IPs = make_set(IPAddress, 5)\n          by AppDisplayName, AppId, ServicePrincipalName\n| sort by Rows desc\n```\n\n`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.",
  "fix": {
    "short": "Developer: replace `resource=<API URI>` with `scope=<API URI>/.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.",
    "steps": "**For the user:** you can't fix this yourself. Report it to IT, with the name of the app.\n\n**For developers:**\n1. Remove `resource` from requests to `/oauth2/v2.0/authorize` and `/oauth2/v2.0/token`.\n2. 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`.\n3. 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`\"*.\n\n**For admins of a third-party product:**\n1. Check which endpoint the product expects. If its documentation asks for a \"resource\" or \"resource URI\", it is built for v1.0.\n2. 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.\n3. 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."
  },
  "labReproduced": null,
  "labSectionText": null,
  "labRuns": [],
  "verification": "documentation",
  "related": [
    "500011",
    "900144",
    "9002313",
    "90014"
  ],
  "coveredBy": [],
  "sources": [
    {
      "title": "Microsoft Entra authentication and authorization error codes",
      "url": "https://learn.microsoft.com/entra/identity-platform/reference-error-codes"
    },
    {
      "title": "Why update to Microsoft identity platform (v2.0)?",
      "url": "https://learn.microsoft.com/en-us/previous-versions/azure/active-directory/azuread-dev/azure-ad-endpoint-comparison"
    },
    {
      "title": "Scopes and permissions in the Microsoft identity platform",
      "url": "https://learn.microsoft.com/entra/identity-platform/scopes-oidc"
    },
    {
      "title": "Microsoft identity platform and the OAuth 2.0 client credentials flow",
      "url": "https://learn.microsoft.com/entra/identity-platform/v2-oauth2-client-creds-grant-flow"
    },
    {
      "title": "Microsoft identity platform and OAuth 2.0 authorization code flow",
      "url": "https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow"
    },
    {
      "title": "SigninLogs table reference (Azure Monitor)",
      "url": "https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs"
    },
    {
      "title": "Configure Cognos Analytics with Azure AD shows AADSTS901002 (IBM Support)",
      "url": "https://www.ibm.com/support/pages/configure-cognos-analytics-azure-ad-show-error-message-aadsts901002-resource-request-parameter-not-supported"
    }
  ],
  "published": "2026-11-01",
  "lastUpdated": "2026-11-01",
  "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, \"AADSTS901002 fix: resource parameter sent to v2.0 endpoint\", https://brambrinkmeier.com/entra/aadsts/901002/ (CC BY 4.0)",
  "microsoftErrorLookup": "https://login.microsoftonline.com/error?code=901002"
}
