{
  "schemaVersion": "1.0",
  "code": "700211",
  "name": null,
  "title": "AADSTS700211: Federated credential issuer doesn't match (fix)",
  "url": "https://brambrinkmeier.com/entra/aadsts/700211/",
  "alternates": {
    "markdown": "https://brambrinkmeier.com/entra/aadsts/700211.md",
    "json": "https://brambrinkmeier.com/api/aadsts/700211.json",
    "html": "https://brambrinkmeier.com/entra/aadsts/700211/"
  },
  "description": "AADSTS700211: the external token's issuer matches no federated identity credential. Wrong issuer URL or no credential for that provider. Fix and KQL.",
  "summary": "AADSTS700211 means a workload sent an external token whose issuer matches none of the federated identity credentials on the app or managed identity. Usually the credential has the wrong issuer URL (a typo, a trailing slash, the wrong cluster or Azure DevOps issuer), or no credential exists for that provider. It is a configuration error with low attack value.",
  "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 AADSTS700211 (checked 30 October 2026). Microsoft's Azure DevOps troubleshooting page does:\n\n> **AADSTS700211: No matching federated identity record found for presented assertion issuer**\n> No federated credential was created or the issuer URL is not correct.\n\nUsers report that the full message names the issuer from the token and adds a hint. From a GitHub issue on the azure-workload-identity project:\n\n> AADSTS700211: No matching federated identity record found for presented assertion issuer '`<issuer from the token>`'. Please check your federated identity credential Subject, Audience and Issuer against the presented assertion.\n\nA federated identity credential trusts tokens from one issuer. Microsoft's restrictions page: the issuer *\"is the URL of the external identity provider and must match the `issuer` claim of the external token being exchanged\"*, and *\"If the `issuer` claim has leading or trailing whitespace in the value, the token exchange is blocked.\"* Microsoft announced case-sensitive matching in August 2024 and rolled it out in stages (see [7002138](https://brambrinkmeier.com/entra/aadsts/7002138/)).\n\n700211 looks like the issuer-specific form of [70021](https://brambrinkmeier.com/entra/aadsts/70021/); Microsoft doesn't say so. Its siblings are [700212](https://brambrinkmeier.com/entra/aadsts/700212/) (audience) and [700213](https://brambrinkmeier.com/entra/aadsts/700213/) (subject). If the app has no federated credentials at all, you get [70025](https://brambrinkmeier.com/entra/aadsts/70025/). Microsoft doesn't document the order in which the three values are checked.",
  "sections": [
    {
      "heading": "What does AADSTS700211 mean?",
      "text": "Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700211 (checked 30 October 2026). Microsoft's Azure DevOps troubleshooting page does:\n\n> **AADSTS700211: No matching federated identity record found for presented assertion issuer**\n> No federated credential was created or the issuer URL is not correct.\n\nUsers report that the full message names the issuer from the token and adds a hint. From a GitHub issue on the azure-workload-identity project:\n\n> AADSTS700211: No matching federated identity record found for presented assertion issuer '`<issuer from the token>`'. Please check your federated identity credential Subject, Audience and Issuer against the presented assertion.\n\nA federated identity credential trusts tokens from one issuer. Microsoft's restrictions page: the issuer *\"is the URL of the external identity provider and must match the `issuer` claim of the external token being exchanged\"*, and *\"If the `issuer` claim has leading or trailing whitespace in the value, the token exchange is blocked.\"* Microsoft announced case-sensitive matching in August 2024 and rolled it out in stages (see [7002138](https://brambrinkmeier.com/entra/aadsts/7002138/)).\n\n700211 looks like the issuer-specific form of [70021](https://brambrinkmeier.com/entra/aadsts/70021/); Microsoft doesn't say so. Its siblings are [700212](https://brambrinkmeier.com/entra/aadsts/700212/) (audience) and [700213](https://brambrinkmeier.com/entra/aadsts/700213/) (subject). If the app has no federated credentials at all, you get [70025](https://brambrinkmeier.com/entra/aadsts/70025/). Microsoft doesn't document the order in which the three values are checked."
    },
    {
      "heading": "Reproduced in the lab",
      "text": "On 30 October 2026 an automated lab run set this up in my own tenant: one app registration presents its access token as a client assertion, and a second app carries the federated identity credential that is supposed to accept it. With the credential's **issuer** set to a different URL than the token's, Entra returned `AADSTS700211`:\n\n> AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/<tenant id>/v2.0'.\n\nThe issuer in the message is the one Entra read from the token, not the one on your credential. Compare it character for character with what the credential has.\n\nThe sign-in log row isn't captured yet; see [how pages are checked](https://brambrinkmeier.com/methodology/)."
    },
    {
      "heading": "Is it an attack?",
      "text": "Usually not.\n\n| Pattern | Likely meaning |\n|---|---|\n| A new federation setup fails on the first run | The issuer on the credential differs from the token's `iss`: a typo, a missing or extra trailing slash, or the wrong URL for the platform. |\n| Azure DevOps fails after converting or recreating a service connection | The credential still holds the other Azure DevOps issuer. Microsoft lists two: `https://vstoken.dev.azure.com/<organization id>` and `https://login.microsoftonline.com/<tenant id>/v2.0` for new connections. |\n| Kubernetes fails after a cluster was rebuilt or the workload moved to another cluster | Each cluster has its own OIDC issuer URL. Likely the credential still points at the old one. |\n| Failures for your app from an issuer and IP you don't use | Someone presenting a token from their own provider with your app's client ID. Our reading: it fails because nothing trusts that issuer. Check, but it is not an incident on its own. |"
    },
    {
      "heading": "How do I find it in my logs (KQL)?",
      "text": "Microsoft doesn't document which sign-in table 700211 lands in. Our reading: app registration failures land in `AADServicePrincipalSignInLogs`, and a user-assigned managed identity may log in the separate managed identity sign-in log, which Microsoft says holds managed identity sign-ins *\"only\"*. Check where it lands in your tenant:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700211\" or ResultSignature == \"700211\"\n| summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable\n```\n\nFailures per app, with the error text and source IPs. `ResultDescription` is documented as *\"the error description for the sign-in operation\"*. Whether it carries the issuer the way the returned message does is our assumption; check a row:\n\n```kusto\nAADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"700211\" or ResultSignature == \"700211\"\n| summarize Failures = count(),\n            FirstSeen = min(TimeGenerated),\n            LastSeen = max(TimeGenerated),\n            Descriptions = make_set(ResultDescription, 5),\n            IPs = make_set(IPAddress, 10)\n          by AppId, ServicePrincipalName\n| sort by Failures desc\n```\n\nAn app that fails from many IPs you don't own, with an issuer you never configured, is the one to look at. That threshold is a judgement call, not a rule."
    },
    {
      "heading": "How do I fix AADSTS700211?",
      "text": "**For developers and pipeline owners:**\n1. Get the issuer from the error message, or decode your provider's token and read `iss`.\n2. Set the credential's issuer to exactly that string: same case, same trailing slash, no spaces. Microsoft's create-trust page shows the GitHub issuer both as `https://token.actions.githubusercontent.com` and with a trailing slash, so go by your token.\n3. Kubernetes: use the cluster's own OIDC issuer URL. Microsoft's example looks like `https://aksoicwesteurope.blob.core.windows.net/<guid>/`.\n4. Azure DevOps: Microsoft says *\"You can fix the issuer URL by editing and then saving a service connection. If Azure DevOps didn't create your identity, you must manually update the issuer.\"* The correct issuer is shown in the service connection's edit dialog.\n\n**For admins:**\n1. List the federated credentials on the app or managed identity and compare the issuers with the token. An app can hold at most 20.\n2. If the issuer in the failures belongs to a provider you never set up, confirm no credential trusts it and review who can edit the app registration."
    }
  ],
  "microsoftWording": {
    "text": "**AADSTS700211: No matching federated identity record found for presented assertion issuer**\nNo federated credential was created or the issuer URL is not correct.",
    "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": "app-config",
      "label": "App configuration"
    },
    "kind": {
      "id": "config",
      "label": "Configuration error"
    },
    "attackSignal": {
      "level": "low",
      "label": "Low: usually configuration or user error"
    },
    "mitre": [],
    "tables": [],
    "isItAnAttack": "Usually not.\n\n| Pattern | Likely meaning |\n|---|---|\n| A new federation setup fails on the first run | The issuer on the credential differs from the token's `iss`: a typo, a missing or extra trailing slash, or the wrong URL for the platform. |\n| Azure DevOps fails after converting or recreating a service connection | The credential still holds the other Azure DevOps issuer. Microsoft lists two: `https://vstoken.dev.azure.com/<organization id>` and `https://login.microsoftonline.com/<tenant id>/v2.0` for new connections. |\n| Kubernetes fails after a cluster was rebuilt or the workload moved to another cluster | Each cluster has its own OIDC issuer URL. Likely the credential still points at the old one. |\n| Failures for your app from an issuer and IP you don't use | Someone presenting a token from their own provider with your app's client ID. Our reading: it fails because nothing trusts that issuer. Check, but it is not an incident on its own. |",
    "conditionalAccess": null
  },
  "kql": [
    {
      "title": null,
      "leadIn": "Microsoft doesn't document which sign-in table 700211 lands in. Our reading: app registration failures land in `AADServicePrincipalSignInLogs`, and a user-assigned managed identity may log in the separate managed identity sign-in log, which Microsoft says holds managed identity sign-ins *\"only\"*. Check where it lands in your tenant:",
      "query": "union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700211\" or ResultSignature == \"700211\"\n| summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable"
    },
    {
      "title": null,
      "leadIn": "Failures per app, with the error text and source IPs. `ResultDescription` is documented as *\"the error description for the sign-in operation\"*. Whether it carries the issuer the way the returned message does is our assumption; check a row:",
      "query": "AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"700211\" or ResultSignature == \"700211\"\n| summarize Failures = count(),\n            FirstSeen = min(TimeGenerated),\n            LastSeen = max(TimeGenerated),\n            Descriptions = make_set(ResultDescription, 5),\n            IPs = make_set(IPAddress, 10)\n          by AppId, ServicePrincipalName\n| sort by Failures desc"
    }
  ],
  "kqlSectionText": "Microsoft doesn't document which sign-in table 700211 lands in. Our reading: app registration failures land in `AADServicePrincipalSignInLogs`, and a user-assigned managed identity may log in the separate managed identity sign-in log, which Microsoft says holds managed identity sign-ins *\"only\"*. Check where it lands in your tenant:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700211\" or ResultSignature == \"700211\"\n| summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable\n```\n\nFailures per app, with the error text and source IPs. `ResultDescription` is documented as *\"the error description for the sign-in operation\"*. Whether it carries the issuer the way the returned message does is our assumption; check a row:\n\n```kusto\nAADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"700211\" or ResultSignature == \"700211\"\n| summarize Failures = count(),\n            FirstSeen = min(TimeGenerated),\n            LastSeen = max(TimeGenerated),\n            Descriptions = make_set(ResultDescription, 5),\n            IPs = make_set(IPAddress, 10)\n          by AppId, ServicePrincipalName\n| sort by Failures desc\n```\n\nAn app that fails from many IPs you don't own, with an issuer you never configured, is the one to look at. That threshold is a judgement call, not a rule.",
  "fix": {
    "short": "Pipeline owner: read the issuer from the error message or the token's `iss` claim, and set the federated credential's issuer to exactly that string: same case, same trailing slash, no spaces. Azure DevOps: edit and save the service connection. Kubernetes: use the cluster's own OIDC issuer URL.",
    "steps": "**For developers and pipeline owners:**\n1. Get the issuer from the error message, or decode your provider's token and read `iss`.\n2. Set the credential's issuer to exactly that string: same case, same trailing slash, no spaces. Microsoft's create-trust page shows the GitHub issuer both as `https://token.actions.githubusercontent.com` and with a trailing slash, so go by your token.\n3. Kubernetes: use the cluster's own OIDC issuer URL. Microsoft's example looks like `https://aksoicwesteurope.blob.core.windows.net/<guid>/`.\n4. Azure DevOps: Microsoft says *\"You can fix the issuer URL by editing and then saving a service connection. If Azure DevOps didn't create your identity, you must manually update the issuer.\"* The correct issuer is shown in the service connection's edit dialog.\n\n**For admins:**\n1. List the federated credentials on the app or managed identity and compare the issuers with the token. An app can hold at most 20.\n2. If the issuer in the failures belongs to a provider you never set up, confirm no credential trusts it and review who can edit the app registration."
  },
  "labReproduced": {
    "date": "2026-10-30",
    "method": "Client-credentials token request with a federated identity credential, against a lab tenant",
    "scenario": "Federated credential: issuer does not match",
    "message": "AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/<tenant id>/v2.0'.",
    "logCaptured": null,
    "kqlTested": null
  },
  "labSectionText": "On 30 October 2026 an automated lab run set this up in my own tenant: one app registration presents its access token as a client assertion, and a second app carries the federated identity credential that is supposed to accept it. With the credential's **issuer** set to a different URL than the token's, Entra returned `AADSTS700211`:\n\n> AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/<tenant id>/v2.0'.\n\nThe issuer in the message is the one Entra read from the token, not the one on your credential. Compare it character for character with what the credential has.\n\nThe sign-in log row isn't captured yet; see [how pages are checked](https://brambrinkmeier.com/methodology/).",
  "labRuns": [
    {
      "date": "2026-10-30",
      "run": "round 5",
      "method": "token-endpoint requests against a lab tenant, using lab-created test apps",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/69",
      "scenario": "Federated credential: issuer does not match",
      "expected": "700211 / 70021",
      "got": "700211",
      "matchedExpectation": true,
      "message": "AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id}"
    },
    {
      "date": "2026-10-30",
      "run": "round 6",
      "method": "token-endpoint requests against a lab tenant, using lab-created test apps",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/70",
      "scenario": "Federated credential: issuer does not match",
      "expected": "700211 / 70021",
      "got": "700211",
      "matchedExpectation": true,
      "message": "AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id}"
    },
    {
      "date": "2026-10-30",
      "run": "round 7",
      "method": "token-endpoint requests against a lab tenant",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/71",
      "scenario": "Federated credential: issuer does not match",
      "expected": "700211 / 70021",
      "got": "700211",
      "matchedExpectation": true,
      "message": "AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id}"
    },
    {
      "date": "2026-10-31",
      "run": "round 8",
      "method": "token-endpoint and device-code requests against a lab tenant",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/72",
      "scenario": "Federated credential: issuer does not match",
      "expected": "700211 / 70021",
      "got": "700211",
      "matchedExpectation": true,
      "message": "AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id}"
    },
    {
      "date": "2026-10-31",
      "run": "round 9",
      "method": "token-endpoint and device-code requests against a lab tenant",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/73",
      "scenario": "Federated credential: issuer does not match",
      "expected": "700211 / 70021",
      "got": "700211",
      "matchedExpectation": true,
      "message": "AADSTS700211: No matching federated identity record found for presented assertion issuer 'https://login.microsoftonline.com/{tenant-id}"
    }
  ],
  "verification": "lab-reproduced",
  "related": [
    "70021",
    "700212",
    "700213",
    "7002138",
    "70025",
    "700226",
    "7002121"
  ],
  "coveredBy": [],
  "sources": [
    {
      "title": "Microsoft Entra authentication and authorization error codes",
      "url": "https://learn.microsoft.com/lb-lu/entra/identity-platform/reference-error-codes"
    },
    {
      "title": "Troubleshoot an Azure Resource Manager workload identity service connection (Azure DevOps)",
      "url": "https://learn.microsoft.com/en-us/azure/devops/pipelines/release/troubleshoot-workload-identity"
    },
    {
      "title": "Important considerations and restrictions for federated identity credentials",
      "url": "https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-considerations"
    },
    {
      "title": "Configure an app to trust an external identity provider",
      "url": "https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust"
    },
    {
      "title": "Federated identity credentials and case-sensitive matching (Microsoft Entra breaking changes, August 2024)",
      "url": "https://learn.microsoft.com/en-us/entra/identity-platform/reference-breaking-changes"
    },
    {
      "title": "azure-workload-identity issue 1613 (GitHub)",
      "url": "https://github.com/Azure/azure-workload-identity/issues/1613"
    },
    {
      "title": "What are service principal sign-ins in Microsoft Entra?",
      "url": "https://learn.microsoft.com/en-my/entra/identity/monitoring-health/concept-service-principal-sign-ins"
    },
    {
      "title": "AADServicePrincipalSignInLogs table reference (Azure Monitor)",
      "url": "https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/aadserviceprincipalsigninlogs"
    }
  ],
  "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, \"AADSTS700211: Federated credential issuer doesn't match (fix)\", https://brambrinkmeier.com/entra/aadsts/700211/ (CC BY 4.0)",
  "microsoftErrorLookup": "https://login.microsoftonline.com/error?code=700211"
}
