{
  "schemaVersion": "1.0",
  "code": "1003031",
  "name": null,
  "title": "AADSTS1003031: Admin consent failed, app lists no API permissions (fix)",
  "url": "https://brambrinkmeier.com/entra/aadsts/1003031/",
  "alternates": {
    "markdown": "https://brambrinkmeier.com/entra/aadsts/1003031.md",
    "json": "https://brambrinkmeier.com/api/aadsts/1003031.json",
    "html": "https://brambrinkmeier.com/entra/aadsts/1003031/"
  },
  "description": "AADSTS1003031: admin consent failed because the app registration lists no API permissions. Unlisted by Microsoft. Cause, fix and KQL.",
  "summary": "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.",
  "inMicrosoftReference": false,
  "unlistedChecked": "2026-10-30",
  "meaningText": "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.\n\nA user on Microsoft Q&A posted this message after opening the tenant-wide admin consent URL for an external tenant:\n\n> AADSTS1003031: Misconfigured required resource access in client application registration.\n\nA 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.\n\nThe 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.\n\nThe URL in question is the one Microsoft documents for tenant-wide admin consent:\n\n```http\nhttps://login.microsoftonline.com/{organization}/adminconsent?client_id={client-id}\n```\n\nA 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.\n\nOn 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\"*.",
  "sections": [
    {
      "heading": "What does AADSTS1003031 mean?",
      "text": "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.\n\nA user on Microsoft Q&A posted this message after opening the tenant-wide admin consent URL for an external tenant:\n\n> AADSTS1003031: Misconfigured required resource access in client application registration.\n\nA 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.\n\nThe 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.\n\nThe URL in question is the one Microsoft documents for tenant-wide admin consent:\n\n```http\nhttps://login.microsoftonline.com/{organization}/adminconsent?client_id={client-id}\n```\n\nA 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.\n\nOn 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\"*."
    },
    {
      "heading": "Is it an attack?",
      "text": "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.\n\n| Pattern | Likely meaning |\n|---|---|\n| An admin hits it once while onboarding a new multi-tenant app | The app registration has no API permissions, as the Microsoft employee describes. |\n| 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). |\n| It keeps happening after permissions were added | Possibly the consent URL still uses another app's client ID. Check the `client_id` value. |\n\nAs 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."
    },
    {
      "heading": "How do I find it in my logs (KQL)?",
      "text": "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:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"1003031\"\n| summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable\n```\n\nWhich app and which admin:\n\n```kusto\nSigninLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"1003031\"\n| summarize Attempts = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)\n    by UserPrincipalName, AppId, AppDisplayName, HomeTenantId, ResourceTenantId\n| sort by LastSeen desc\n```\n\n`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."
    },
    {
      "heading": "How do I fix AADSTS1003031?",
      "text": "**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.\n\n**For developers:**\n1. Open the app registration in the developer's (home) tenant. Go to **API permissions**.\n2. 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.\n3. 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.\n4. 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.\n\n**For admins** (in the tenant granting consent):\n1. 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.\"*\n2. 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.\n3. If the developer can't fix the registration quickly, the Microsoft employee's answer gives a workaround: create the service principal yourself.\n\n```powershell\nConnect-MgGraph -Scopes Application.ReadWrite.All\nNew-MgServicePrincipal -BodyParameter @{ AppId = \"<client id of the app>\" }\n```\n\nOur reading: this only adds the app to your tenant. Any permissions still need consent once the developer has added them."
    }
  ],
  "microsoftWording": {
    "text": "AADSTS1003031: Misconfigured required resource access in client application registration.",
    "source": "Quoted on the page from the lab or from user reports; the code is not in Microsoft's error code reference",
    "sourceUrl": null
  },
  "securityReading": {
    "category": {
      "id": "consent",
      "label": "Consent and app permissions"
    },
    "kind": {
      "id": "config",
      "label": "Configuration error"
    },
    "attackSignal": {
      "level": "low",
      "label": "Low: usually configuration or user error"
    },
    "mitre": [],
    "tables": [],
    "isItAnAttack": "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.\n\n| Pattern | Likely meaning |\n|---|---|\n| An admin hits it once while onboarding a new multi-tenant app | The app registration has no API permissions, as the Microsoft employee describes. |\n| 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). |\n| It keeps happening after permissions were added | Possibly the consent URL still uses another app's client ID. Check the `client_id` value. |\n\nAs 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.",
    "conditionalAccess": null
  },
  "kql": [
    {
      "title": null,
      "leadIn": "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:",
      "query": "union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"1003031\"\n| summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable"
    },
    {
      "title": null,
      "leadIn": "Which app and which admin:",
      "query": "SigninLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"1003031\"\n| summarize Attempts = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)\n    by UserPrincipalName, AppId, AppDisplayName, HomeTenantId, ResourceTenantId\n| sort by LastSeen desc"
    }
  ],
  "kqlSectionText": "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:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"1003031\"\n| summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable\n```\n\nWhich app and which admin:\n\n```kusto\nSigninLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"1003031\"\n| summarize Attempts = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)\n    by UserPrincipalName, AppId, AppDisplayName, HomeTenantId, ResourceTenantId\n| sort by LastSeen desc\n```\n\n`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.",
  "fix": {
    "short": "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.",
    "steps": "**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.\n\n**For developers:**\n1. Open the app registration in the developer's (home) tenant. Go to **API permissions**.\n2. 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.\n3. 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.\n4. 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.\n\n**For admins** (in the tenant granting consent):\n1. 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.\"*\n2. 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.\n3. If the developer can't fix the registration quickly, the Microsoft employee's answer gives a workaround: create the service principal yourself.\n\n```powershell\nConnect-MgGraph -Scopes Application.ReadWrite.All\nNew-MgServicePrincipal -BodyParameter @{ AppId = \"<client id of the app>\" }\n```\n\nOur reading: this only adds the app to your tenant. Any permissions still need consent once the developer has added them."
  },
  "labReproduced": null,
  "labSectionText": null,
  "labRuns": [],
  "verification": "documentation",
  "related": [
    "650056",
    "65001",
    "90094",
    "700016"
  ],
  "coveredBy": [],
  "sources": [
    {
      "title": "Microsoft Entra authentication and authorization error codes",
      "url": "https://learn.microsoft.com/entra/identity-platform/reference-error-codes"
    },
    {
      "title": "How to setup an external tenant user to access the host tenant web app (Microsoft Q&A)",
      "url": "https://learn.microsoft.com/en-us/answers/questions/2287290/how-to-setup-an-external-tenant-user-to-access-the"
    },
    {
      "title": "SSO for site not working (Microsoft Q&A)",
      "url": "https://learn.microsoft.com/en-us/answers/questions/890443/sso-for-site-not-working"
    },
    {
      "title": "Cant share team app with other organizations (Microsoft Q&A)",
      "url": "https://learn.microsoft.com/en-us/answers/questions/8bc571bd-1d19-4928-a517-e7e6c1eea72a/cant-share-team-app-with-other-organizations?forum=msteams-all"
    },
    {
      "title": "Grant tenant-wide admin consent to an application",
      "url": "https://learn.microsoft.com/entra/identity/enterprise-apps/grant-admin-consent"
    },
    {
      "title": "SigninLogs table reference (Azure Monitor)",
      "url": "https://docs.azure.cn/en-us/azure-monitor/reference/tables/SigninLogs"
    }
  ],
  "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, \"AADSTS1003031: Admin consent failed, app lists no API permissions (fix)\", https://brambrinkmeier.com/entra/aadsts/1003031/ (CC BY 4.0)",
  "microsoftErrorLookup": "https://login.microsoftonline.com/error?code=1003031"
}
