AADSTS70021: No matching federated identity credential (fix)
Short answer: AADSTS70021 means a workload sent an external token (from GitHub, Azure DevOps, Kubernetes or another identity provider) and Entra found no federated identity credential on the app or managed identity that matches it. Usually the issuer or subject is wrong, or the credential was created minutes ago and hasn't propagated. It is a configuration error with low attack value.
Fix: Developer: if you created the credential minutes ago, wait and retry. Otherwise compare the issuer and subject in the error or token with the federated credential, character by character (case-sensitive, no wildcards), and check the audience. Azure DevOps after a rename: update the sc:// subject. Full steps
| Code | AADSTS70021 |
|---|---|
| In Microsoft's error reference | No (checked ). Wording on this page is what Entra returned or what users report. |
| Category | App configuration |
| Type | Configuration error |
| Attack signal | Low: usually configuration or user error |
| Microsoft lookup | login.microsoftonline.com/error?code=70021 |
What does AADSTS70021 mean?
Section titled “What does AADSTS70021 mean?”Microsoft’s error code reference doesn’t list AADSTS70021 (checked 30 October 2026). Microsoft does document it on two other pages.
Microsoft’s page on federated identity credential restrictions quotes the message:
AADSTS70021: No matching federated identity record found for presented assertion.
It gives it in one specific context, propagation after setup:
It takes time for the federated identity credential to be propagated throughout a region after being initially configured. A token request made several minutes after configuring the federated identity credential may fail because the cache is populated in the directory with old data.
Microsoft’s Azure DevOps troubleshooting page lists two longer forms of the same message, with the values from the token appended:
| Message (Azure DevOps doc) | Cause Microsoft gives |
|---|---|
No matching federated identity record found for presented assertion. Assertion Issuer: 'https://app.vstoken.visualstudio.com'. |
“No federated credential was created or the issuer URL isn’t correct.” |
No matching federated identity record found for presented assertion. Assertion Issuer: 'https://login.microsoftonline.com/<tenant>'. Assertion Subject: 'sc://<org>/<project>/<service-connection>'. |
“Either the issuer URL or the federation subject doesn’t match. The Azure DevOps organization or project was renamed or a manually created service connection was renamed without updating the federation subject on the identity.” |
Background: with workload identity federation, a workload outside Entra (a GitHub Actions job, an Azure DevOps pipeline, a Kubernetes pod) gets a token from its own identity provider and exchanges it for an Entra access token. Microsoft’s overview: “Microsoft identity platform checks the trust relationship on the user-assigned managed identity or app registration and validates the external token against the OpenID Connect (OIDC) issuer URL on the external IdP.” The trust is a federated identity credential with three values. The Graph overview says they “must match exactly”, case-sensitively, against the token’s iss, sub and aud claims. 70021 means no credential on the app matched.
Our reading: 70021 is the general “no match” code. The more specific codes say which value failed: 700211 (issuer), 700212 (audience), 700213 (subject) and 7002138 (subject differs only in letter case). If the app has no federated credentials at all, you get 70025 instead. Microsoft doesn’t document when Entra returns 70021 rather than one of the specific codes.
One related code is in the reference: AADSTS700229 ForbiddenTokenType, “Only app-only tokens can be used as Federated Identity Credentials for Microsoft Entra issuer”.
Is it an attack?
Section titled “Is it an attack?”Almost never. It is a mismatch between what a workload sends and what the app trusts.
| Pattern | Likely meaning |
|---|---|
| A new credential, and the first run fails within minutes | Propagation delay, as Microsoft describes. Retry after a short wait. |
| An Azure DevOps pipeline that worked and now fails | The organization, project or service connection was renamed, so the sc:// subject changed. Microsoft’s cause. |
| A pipeline or workflow that never worked | Wrong issuer or subject on the credential. Microsoft’s create-trust page: a wrong subject is saved “without error. The error does not become apparent until the token exchange fails.” |
| Failures for your app from an IP and identity provider you don’t use | Someone presenting a token from their own provider with your app’s client ID. Likely it fails exactly because no credential trusts that provider, but we haven’t tested this. Worth a look, not an incident. |
Our reading: the attack to watch for is the opposite case. An attacker who can edit your app registration adds a federated credential that trusts their own provider, and then signs in successfully. That shows as a success with a new FederatedCredentialId, plus an audit event, not as 70021.
How do I find it in my logs (KQL)?
Section titled “How do I find it in my logs (KQL)?”Microsoft doesn’t document which sign-in table 70021 lands in. An app registration’s federated sign-in is a service principal sign-in, so the failure probably lands in AADServicePrincipalSignInLogs. Microsoft’s service principal sign-ins page says managed identity sign-ins are “included only in the managed identity sign-in log”, so a failing user-assigned managed identity may log there instead (AADManagedIdentitySignInLogs). Check where it lands in your tenant:
union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs| where TimeGenerated > ago(30d)| where ResultType == "70021" or ResultSignature == "70021"| summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTableThe ResultSignature check is there because the Azure Monitor reference describes ResultType in AADServicePrincipalSignInLogs only as “Success or Failure”. Look at a failed row to see which column carries the code in your workspace.
For an app that worked before and now fails, find its last successful federated sign-in and which credential it used. The Graph sign-in reference lists federatedIdentityCredential as a value of clientCredentialType, and describes federatedCredentialId as “the identifier of an application’s federated identity credential, if a federated identity credential was used to sign in”. That the Log Analytics columns carry the same values is our reading:
let failing = AADServicePrincipalSignInLogs | where TimeGenerated > ago(7d) | where ResultType == "70021" or ResultSignature == "70021" | distinct AppId;AADServicePrincipalSignInLogs| where TimeGenerated > ago(30d)| where AppId in (failing)| where ClientCredentialType == "federatedIdentityCredential"| where ResultType == "0"| summarize arg_max(TimeGenerated, FederatedCredentialId, IPAddress) by AppId, ServicePrincipalNameThen check whether someone changed the app’s federated credentials around that time. A third-party write-up (trackr.live) reports that this logs as Update application with a modified property named FederatedIdentityCredentials. Microsoft doesn’t document that property name on the pages we checked, so treat this as a starting point:
AuditLogs| where TimeGenerated > ago(30d)| where OperationName == "Update application"| mv-expand Target = TargetResources| mv-expand Prop = Target.modifiedProperties| where tostring(Prop.displayName) == "FederatedIdentityCredentials"| project TimeGenerated, App = tostring(Target.displayName), Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)), OldValue = tostring(Prop.oldValue), NewValue = tostring(Prop.newValue)The same write-up says credentials on a user-assigned managed identity are an Azure Resource Manager write and don’t appear in the Entra audit log. Look in the Azure activity log for those.
How do I fix AADSTS70021?
Section titled “How do I fix AADSTS70021?”For developers and pipeline owners:
- If you created the credential minutes ago, wait and retry. Microsoft: “wait a short time after adding the federated identity credential before requesting a token”, and add retry logic to token requests.
- Read the issuer and subject from the error message (the Azure DevOps forms include them) or from your provider’s token, and compare them character by character with the credential. Matching is case-sensitive and “Wildcard characters aren’t supported in any federated identity credential property value.”
- Check the formats Microsoft gives:
- GitHub Actions: issuer
https://token.actions.githubusercontent.com(Microsoft’s page shows it both with and without a trailing slash; match your token’siss); subjectrepo:<org>/<repo>:environment:<name>for jobs tied to an environment, otherwiserepo:<org>/<repo>:ref:<ref path>, orrepo:<org>/<repo>:pull-request. - Kubernetes: issuer is the cluster’s OIDC issuer URL; subject
system:serviceaccount:<namespace>:<service account>. - Azure DevOps: see the issuer table on Microsoft’s troubleshooting page. New service connections use
https://login.microsoftonline.com/<tenant id>/v2.0.
- GitHub Actions: issuer
- Check the audience. Microsoft recommends
api://AzureADTokenExchange. If only the audience is wrong, you may see 700212.
For admins:
- For Azure DevOps after a rename, Microsoft names the cause but gives no fix. Update the federation subject on the app or managed identity to the new
sc://value. For a wrong issuer, Microsoft’s fix is to edit and save the service connection. If Azure DevOps didn’t create the identity, update the issuer yourself. - An app or user-assigned managed identity can hold at most 20 federated credentials. If you need one per branch or environment, plan for that limit.
- If failures come from a provider you don’t use, confirm no unexpected federated credential exists on the app, and review who can edit the app registration.
Related codes
- AADSTS700211: Federated credential issuer doesn't match
- AADSTS700212: Federated credential audience doesn't match
- AADSTS700213: Federated credential subject doesn't match
- AADSTS7002138: Federated credential subject differs in case
- AADSTS70025: App has no federated identity credentials
- AADSTS700016: Application not found in the directory
Sources
- Microsoft Entra authentication and authorization error codes
- Important considerations and restrictions for federated identity credentials
- Troubleshoot an Azure Resource Manager workload identity service connection (Azure DevOps)
- Workload identity federation
- Configure an app to trust an external identity provider
- Overview of federated identity credentials (Microsoft Graph)
- What are service principal sign-ins in Microsoft Entra?
- AADServicePrincipalSignInLogs table reference (Azure Monitor)
- signIn resource type (Microsoft Graph)
- A Federated Identity Credential Adds No Secret (trackr.live, third-party)