AADSTS901002 fix: resource parameter sent to v2.0 endpoint
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=<API>` with `scope=<API>/.default`, or point the app at the v1.0 endpoints it was built for.
Fix: 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. Full steps
| Code | AADSTS901002 |
|---|---|
| Category | App configuration |
| Type | Configuration error |
| Attack signal | Low: usually configuration or user error |
| Microsoft lookup | login.microsoftonline.com/error?code=901002 |
What does AADSTS901002 mean?
Section titled “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. 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?
Section titled “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)?
Section titled “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:
union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs| where TimeGenerated > ago(7d)| where ResultType == "901002"| summarize Rows = count(), Apps = dcount(AppId) by SourceTableWhich apps send the v1.0 parameter, and since when:
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 descAppDisplayName 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?
Section titled “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:
- Remove
resourcefrom requests to/oauth2/v2.0/authorizeand/oauth2/v2.0/token. - Put the API in
scopeinstead. For the same access asresource=https://graph.microsoft.com, sendscope=https://graph.microsoft.com/.default. For specific delegated permissions, append them to the API identifier, as in Microsoft’s examplehttps://graph.microsoft.com/Calendars.Read. - For the client credentials flow,
scopeis 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:
- Check which endpoint the product expects. If its documentation asks for a “resource” or “resource URI”, it is built for v1.0.
- Then configure the v1.0 URLs, without
v2.0in the path. Microsoft’s comparison page shows the v1.0 authorize request ashttps://login.microsoftonline.com/common/oauth2/authorize. It doesn’t show the token URL; our reading is that it is.../oauth2/tokenon the same pattern. - 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.
Related codes
- AADSTS500011: The resource principal was not found in the tenant
- AADSTS900144: Request body is missing a required parameter
- AADSTS9002313: Request is malformed or invalid
- AADSTS90014: required field missing from the request
Sources
- Microsoft Entra authentication and authorization error codes
- Why update to Microsoft identity platform (v2.0)?
- Scopes and permissions in the Microsoft identity platform
- Microsoft identity platform and the OAuth 2.0 client credentials flow
- Microsoft identity platform and OAuth 2.0 authorization code flow
- SigninLogs table reference (Azure Monitor)
- Configure Cognos Analytics with Azure AD shows AADSTS901002 (IBM Support)