Microsoft Entra token errors for apps and service principals (AADSTS)

Look up an AADSTS error from a token request made by an app, a service principal or a script — tenant or app not found, missing service principal, bad or expired secret or certificate, wrong scope or resource, consent and admin consent, multitenant and /common errors — each with the cause, the check that confirms it, and the fix. User sign-in and federated-credential errors have their own catalogues.

markdownreferencev1JB2M-G52Bstage: operatetrust: officialtrust: fieldservice: entrainterface: anyAADSTSAADSTS700016AADSTS90002AADSTS50194AADSTS7000215AADSTS7000222AADSTS7000218AADSTS70002AADSTS700027AADSTS7000112AADSTS500014AADSTS500011AADSTS50001AADSTS70011AADSTS650057AADSTS650056AADSTS65001AADSTS90094AADSTS90009AADSTS50011AADSTS900144AADSTS9002313invalid_clientinvalid_scopeunauthorized_clientinvalid_resourceclient secret expiredapplication not found in the directory.default scopeadmin consent required

Created 21 Oct 2026 · Modified 23 Oct 2026 · 1 version

Microsoft Entra token errors for apps and service principals

An AADSTS error comes from the token request, before any Azure service sees your call. Fix it here, not in the service. The response JSON carries error (an OAuth class such as invalid_client), error_description (starts with AADSTS<n>:), error_codes, trace_id, correlation_id and error_uri. Branch code on error or error_codes, never on the description text: Microsoft says the wording changes. The live description of any code is at https://login.microsoftonline.com/error?code=<n>.

In the Azure SDK for JavaScript, these arrive as AuthenticationRequiredError or AuthenticationError with the AADSTS line inside the message (reference/azure-identity/errors.md).

Two checks used below:

  • App lookup: az ad app show --id <client-id> --query "{appId:appId, audience:signInAudience}", run while signed in to the tenant in the request (az login --tenant <tenant-id>).
  • SP lookup: az ad sp show --id <client-id> --query "{enabled:accountEnabled, tenant:appOwnerOrganizationId}" in the same tenant.

Tenant, app and service principal

CodeCause → fixCheck
AADSTS90002 InvalidTenantNameThe tenant in the URL wasn't found. Check the tenant ID; prefer the GUID to a domain namecurl -s https://login.microsoftonline.com/<tenant>/v2.0/.well-known/openid-configuration returns an error
AADSTS700016 UnauthorizedClient_DoesNotMatchRequestNo app with this client ID in this tenant: wrong client ID or wrong tenant, or a multitenant app with no service principal here yet (needs consent by that tenant's admin)SP lookup in the requesting tenant returns nothing
AADSTS7000112 UnauthorizedClientApplicationDisabledThe app's service principal is disabledSP lookup → enabled: false
AADSTS500014The resource's service principal is disabled (a lapsed subscription or an admin disabled it)az ad sp show --id <resource-app-id> → accountEnabled
AADSTS500011 InvalidResourceServicePrincipalNotFoundThe resource (API) has no service principal in this tenant: wrong resource URI, or a third-party API nobody has consented to hereaz ad sp show --id <resource-app-id-or-uri> returns nothing
AADSTS50194A single-tenant app called /common. Use https://login.microsoftonline.com/<tenant-id>/…, or make the app multitenantApp lookup → audience: AzureADMyOrg
AADSTS90009The app asked for a token for itself by its URI. Use its GUID app ID as the resourceCompare the scope's resource with the client ID

Created with az ad app create, then nothing works? Registering in the portal creates the app object and its service principal; creating through Microsoft Graph, which the CLI uses, creates only the app. Run az ad sp create --id <client-id>. (az ad sp create-for-rbac creates both, plus a one-year secret, and assigns no role unless you pass --role and --scopes.)

Credentials

CodeCause → fixCheck
AADSTS7000215Invalid client secret. The message itself says to send the secret's value, not its ID; field sources name that mix-up as the usual cause. Otherwise the secret was deleted or belongs to another appaz ad app credential list --id <client-id> → is there a keyId you recognise? The value can't be read back: create a new secret
AADSTS7000222 InvalidClientSecretExpiredKeysProvidedThe secret expired. Create a new one, or switch to a certificate or a federated credentialSame call → endDateTime in the past
AADSTS70002 InvalidClientThe client_secret doesn't match the expected value for this clientConfirm the client ID and the secret come from the same app registration
AADSTS7000218The request body has no client_secret or client_assertion: the app is a confidential client and no credential was sent (in scripts, typically an unset variable: the hub's reading)Print which of AZURE_CLIENT_SECRET, AZURE_CLIENT_CERTIFICATE_PATH is set (not its value)
AADSTS700027Client assertion failed signature validation: the certificate used to sign isn't one uploaded to the app, or the wrong private keyaz ad app credential list --id <client-id> --cert → compare thumbprints with your certificate
AADSTS900144A required parameter is missing from the body (grant_type, client_id, scope). The message names itLog the form body keys (not values)
AADSTS9002313 InvalidRequestMalformed request to the endpoint. Microsoft suggests capturing the request (a Fiddler trace); the token endpoint takes an application/x-www-form-urlencoded bodyThe captured request's body and Content-Type
CodeCause → fixCheck
AADSTS70011 InvalidScopeBad scope. App-only (client credentials) tokens need <resource>/.default, for one resource per request: https://management.azure.com/.default, https://vault.azure.net/.default, https://graph.microsoft.com/.defaultThe scope value in the request
AADSTS50001 InvalidResourceThe resource URI doesn't exist or is disabled (typo, wrong cloud)az ad sp show --id <resource-uri>
AADSTS650057The app requested a resource that isn't in its API permissions (required resource access)az ad app permission list --id <client-id>
AADSTS650056Misconfigured app: no permissions listed for that resource, or admin consent missing for themSame call, then az ad app permission list-grants --id <client-id> --show-resource-name
AADSTS65001 DelegationDoesNotExistNo consent for this app and resource. Interactive users can consent; for daemons, an admin grants the application permissionsaz ad app permission list-grants --id <client-id> --show-resource-name
AADSTS90094 AdminConsentRequiredThe permissions requested need an administrator. Ask one to run az ad app permission admin-consent --id <client-id> or use the admin consent endpointSame call shows no grant
AADSTS50011 InvalidReplyToThe redirect URI sent is missing from, or doesn't match, the app's registered reply addresses. Add the exact URIaz ad app show --id <client-id> --query "{web:web.redirectUris, spa:spa.redirectUris, public:publicClient.redirectUris}"

App permissions vs delegated: a token for an app with no user carries a roles claim (application permissions, granted by an admin); scp appears only in user tokens. A daemon that was given only delegated permissions gets a token with no roles, so the failure shows up at the API (401 or 403), not as an AADSTS error (the hub's reading).

When none of these fits

Search the code at https://login.microsoftonline.com/error?code=<n>, check that the client ID, tenant ID and credential all come from the same app registration, and keep the trace_id and correlation_id from the response for support. A user-interactive failure (MFA, conditional access, password) is in reference/entra/sign-in-errors.md; a federated credential failure (AADSTS70021, AADSTS7002xx) is in reference/entra/federated-credential-errors.md.

Read this document as markdown — the same bytes an agent receives.