{
  "schemaVersion": "1.0",
  "code": "700226",
  "name": null,
  "title": "AADSTS700226: Only managed identity tokens work with the Entra ID issuer (fix)",
  "url": "https://brambrinkmeier.com/entra/aadsts/700226/",
  "alternates": {
    "markdown": "https://brambrinkmeier.com/entra/aadsts/700226.md",
    "json": "https://brambrinkmeier.com/api/aadsts/700226.json",
    "html": "https://brambrinkmeier.com/entra/aadsts/700226/"
  },
  "description": "AADSTS700226: an Entra-issuer federated credential only accepts managed identity tokens. Not in Microsoft's error list. What it means and how to fix it.",
  "summary": "AADSTS700226 means a federated identity credential whose issuer is a Microsoft Entra tenant was presented with a token that is not a managed identity token. Microsoft's error reference doesn't list it. The Entra ID issuer exists for the managed identity scenario only, so you can't federate one app registration to another this way. 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 AADSTS700226 (checked 30 October 2026). The wording below is from a lab run:\n\n> AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer.\n\nA public repository of federated-credential experiments records the same line, with the trigger: *\"AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer.\" (when trying to use tokens from app registration to another app registration)*.\n\n\"MSI\" is managed service identity, the older name for a managed identity. \"AAD issuer\" means a federated identity credential whose issuer is a Microsoft Entra tenant itself, in the form `https://login.microsoftonline.com/<tenant id>/v2.0`, rather than GitHub, Kubernetes or another external provider.\n\n### Why this is worth knowing\nWorkload identity federation lets an app registration accept a token from somewhere else instead of holding a secret. One of its configurations uses Entra as the issuer. Microsoft documents that configuration for exactly one case: an app registration trusting a **managed identity**. From Microsoft's page on configuring an app to trust a managed identity:\n\n- *\"issuer is the URL of the Microsoft Entra tenant's Authority URL in the form `https://login.microsoftonline.com/{tenant}/v2.0`. Both the Microsoft Entra app and managed identity must belong to the same tenant.\"*\n- The issuer field in the portal is described as *\"the OAuth 2.0 / OIDC issuer URL of the Microsoft Entra ID authority that issues the managed identity token. This value is automatically populated with the current Entra tenant issuer.\"*\n- *\"subject: This is the case-sensitive GUID of the managed identity's Object (Principal) ID assigned to the Azure workload.\"*\n- *\"Select managed identity: Click on this link to select the managed identity that will act as the federated identity credential. You can only use User-Assigned Managed Identities as a credential.\"*\n\nOur reading: 700226 is the runtime half of that restriction. The configuration will accept an Entra issuer and a subject GUID, so nothing stops you entering another app registration's service principal object ID and expecting that app's own token to be exchanged. At token time Entra checks the presented token's type and refuses it. So **app registration to app registration federation through the Entra issuer does not work**, however correct the issuer, subject and audience look. Microsoft's pages describe the managed identity case and do not state the refusal, which is why the error has no documented wording.\n\nThis matters if you were planning to give one app registration access to another tenant's or another app's resources without a secret. The supported routes are a client secret, a certificate credential, an external identity provider as the issuer, or on-behalf-of for a user's token.\n\nThe siblings cover the other federated failures: [70025](https://brambrinkmeier.com/entra/aadsts/70025/) (no credential at all), [700211](https://brambrinkmeier.com/entra/aadsts/700211/) (issuer), [700213](https://brambrinkmeier.com/entra/aadsts/700213/) (subject), [7002121](https://brambrinkmeier.com/entra/aadsts/7002121/) and [700212](https://brambrinkmeier.com/entra/aadsts/700212/) (audience). 700226 is different in kind: the three values matched and the token was still refused.",
  "sections": [
    {
      "heading": "What does AADSTS700226 mean?",
      "text": "Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700226 (checked 30 October 2026). The wording below is from a lab run:\n\n> AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer.\n\nA public repository of federated-credential experiments records the same line, with the trigger: *\"AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer.\" (when trying to use tokens from app registration to another app registration)*.\n\n\"MSI\" is managed service identity, the older name for a managed identity. \"AAD issuer\" means a federated identity credential whose issuer is a Microsoft Entra tenant itself, in the form `https://login.microsoftonline.com/<tenant id>/v2.0`, rather than GitHub, Kubernetes or another external provider.\n\n### Why this is worth knowing\nWorkload identity federation lets an app registration accept a token from somewhere else instead of holding a secret. One of its configurations uses Entra as the issuer. Microsoft documents that configuration for exactly one case: an app registration trusting a **managed identity**. From Microsoft's page on configuring an app to trust a managed identity:\n\n- *\"issuer is the URL of the Microsoft Entra tenant's Authority URL in the form `https://login.microsoftonline.com/{tenant}/v2.0`. Both the Microsoft Entra app and managed identity must belong to the same tenant.\"*\n- The issuer field in the portal is described as *\"the OAuth 2.0 / OIDC issuer URL of the Microsoft Entra ID authority that issues the managed identity token. This value is automatically populated with the current Entra tenant issuer.\"*\n- *\"subject: This is the case-sensitive GUID of the managed identity's Object (Principal) ID assigned to the Azure workload.\"*\n- *\"Select managed identity: Click on this link to select the managed identity that will act as the federated identity credential. You can only use User-Assigned Managed Identities as a credential.\"*\n\nOur reading: 700226 is the runtime half of that restriction. The configuration will accept an Entra issuer and a subject GUID, so nothing stops you entering another app registration's service principal object ID and expecting that app's own token to be exchanged. At token time Entra checks the presented token's type and refuses it. So **app registration to app registration federation through the Entra issuer does not work**, however correct the issuer, subject and audience look. Microsoft's pages describe the managed identity case and do not state the refusal, which is why the error has no documented wording.\n\nThis matters if you were planning to give one app registration access to another tenant's or another app's resources without a secret. The supported routes are a client secret, a certificate credential, an external identity provider as the issuer, or on-behalf-of for a user's token.\n\nThe siblings cover the other federated failures: [70025](https://brambrinkmeier.com/entra/aadsts/70025/) (no credential at all), [700211](https://brambrinkmeier.com/entra/aadsts/700211/) (issuer), [700213](https://brambrinkmeier.com/entra/aadsts/700213/) (subject), [7002121](https://brambrinkmeier.com/entra/aadsts/7002121/) and [700212](https://brambrinkmeier.com/entra/aadsts/700212/) (audience). 700226 is different in kind: the three values matched and the token was still refused."
    },
    {
      "heading": "Reproduced in the lab",
      "text": "On 30 October 2026 an automated lab run configured a federated identity credential on an app registration, using the lab tenant itself as the issuer (`https://login.microsoftonline.com/<tenant id>/v2.0`), and presented a normal app token in a client-credentials request. The run expected a token, because the credential's issuer, subject and audience were the ones the presented token carried. Entra returned:\n\n> AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer.\n\nThe run calls this scenario \"Federated credential matches\", and that is what makes the code useful: in the same run a mismatch on one of the three values gave [700211](https://brambrinkmeier.com/entra/aadsts/700211/), [700213](https://brambrinkmeier.com/entra/aadsts/700213/) or [7002121](https://brambrinkmeier.com/entra/aadsts/7002121/). 700226 is what Entra returns when those three match and the token is still the wrong kind. The lab did not test the supported arrangement, so it confirms the refusal, not that a managed identity token would have been accepted.\n\nNo sign-in log row was captured. See [how pages are checked](https://brambrinkmeier.com/methodology/)."
    },
    {
      "heading": "Is it an attack?",
      "text": "No. It is a design limit being hit by a configuration someone built on purpose.\n\n| Pattern | Likely meaning |\n|---|---|\n| A new integration fails on its first run, with issuer, subject and audience all verified correct | Someone federated one app registration to another. That is what 700226 refuses. |\n| A workload that used to work starts failing | The workload now presents an app token instead of its managed identity token, for example after moving off an Azure host or switching to a client secret in configuration. |\n| The subject in the credential is a service principal object ID rather than a managed identity's Object (Principal) ID | The credential points at the wrong principal. Only a user-assigned managed identity works here. |\n\nOur reading on the security side: 700226 is a refusal, so a row means the exchange did not happen. It is worth noticing if you did not configure an Entra-issuer credential at all, because someone added a federated credential to one of your apps. Credential additions are in the audit log, not the sign-in log."
    },
    {
      "heading": "How do I find it in my logs (KQL)?",
      "text": "Which table 700226 lands in is undocumented. Our reading: the app registration whose credential was used is the one signing in, so `AADServicePrincipalSignInLogs` is the likely place. Check with a union first:\n\n```kusto\nunion withsource=SourceTable\n    SigninLogs,\n    AADNonInteractiveUserSignInLogs,\n    AADServicePrincipalSignInLogs,\n    AADManagedIdentitySignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700226\" or ResultSignature == \"700226\"\n| summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable\n```\n\nThe filter covers both columns because the tables document them differently: in `SigninLogs`, `ResultType` *\"provides the 5-6 digit error code\"*, while in `AADServicePrincipalSignInLogs` it is described as *\"Success or Failure\"* and `ResultSignature` as *\"the error code, if any, for the sign-in operation\"*.\n\nWhich app and which credential:\n\n```kusto\nAADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700226\" or ResultSignature == \"700226\"\n| summarize Failures = count(),\n            LastSeen = max(TimeGenerated),\n            Credentials = make_set(FederatedCredentialId, 5),\n            CredentialTypes = make_set(ClientCredentialType, 5),\n            IPs = make_set(IPAddress, 10)\n          by AppId, ServicePrincipalName\n| sort by Failures desc\n```\n\n`FederatedCredentialId` is documented as *\"Th identifier of an application's federated identity credential if a federated identity credential was used to sign in\"* (Microsoft's typo). Whether it is populated on a refusal is not documented, so confirm on a row of your own."
    },
    {
      "heading": "How does Conditional Access affect it?",
      "text": "Nothing to configure here. The request fails on the token type before any policy decision matters, and a federated credential exchange for an app carries no user and no MFA step."
    },
    {
      "heading": "How do I fix AADSTS700226?",
      "text": "**For developers:**\n1. If the workload runs on Azure, give it a **user-assigned managed identity** and present that identity's token. Set the credential's subject to the managed identity's **Object (Principal) ID**, exactly as Microsoft's page requires, and keep both objects in the same tenant.\n2. If the caller is an app registration and not a managed identity, stop using the Entra issuer. Use a client secret or a certificate credential on that app, or on-behalf-of when you are acting for a signed-in user.\n3. If the caller is outside Azure, use its own provider as the issuer: GitHub, Kubernetes or any OIDC provider that signs with RS256. Microsoft's restrictions page: *\"Only issuers that provide tokens signed using the RS256 algorithm are supported for token exchange using workload identity federation.\"*\n\n**For admins:**\n1. Check the federated credential's subject. It must be a user-assigned managed identity's Object (Principal) ID, not an app's service principal object ID.\n2. Both objects must be in the same tenant. Microsoft: *\"Both the Microsoft Entra app and managed identity must belong to the same tenant.\"*\n3. If you did not expect an Entra-issuer credential on this app, review who added it and why, in the audit log."
    }
  ],
  "microsoftWording": {
    "text": "AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer.",
    "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": [
      "AADServicePrincipalSignInLogs"
    ],
    "isItAnAttack": "No. It is a design limit being hit by a configuration someone built on purpose.\n\n| Pattern | Likely meaning |\n|---|---|\n| A new integration fails on its first run, with issuer, subject and audience all verified correct | Someone federated one app registration to another. That is what 700226 refuses. |\n| A workload that used to work starts failing | The workload now presents an app token instead of its managed identity token, for example after moving off an Azure host or switching to a client secret in configuration. |\n| The subject in the credential is a service principal object ID rather than a managed identity's Object (Principal) ID | The credential points at the wrong principal. Only a user-assigned managed identity works here. |\n\nOur reading on the security side: 700226 is a refusal, so a row means the exchange did not happen. It is worth noticing if you did not configure an Entra-issuer credential at all, because someone added a federated credential to one of your apps. Credential additions are in the audit log, not the sign-in log.",
    "conditionalAccess": {
      "heading": "How does Conditional Access affect it?",
      "text": "Nothing to configure here. The request fails on the token type before any policy decision matters, and a federated credential exchange for an app carries no user and no MFA step."
    }
  },
  "kql": [
    {
      "title": null,
      "leadIn": "Which table 700226 lands in is undocumented. Our reading: the app registration whose credential was used is the one signing in, so `AADServicePrincipalSignInLogs` is the likely place. Check with a union first:",
      "query": "union withsource=SourceTable\n    SigninLogs,\n    AADNonInteractiveUserSignInLogs,\n    AADServicePrincipalSignInLogs,\n    AADManagedIdentitySignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700226\" or ResultSignature == \"700226\"\n| summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable"
    },
    {
      "title": null,
      "leadIn": "Which app and which credential:",
      "query": "AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700226\" or ResultSignature == \"700226\"\n| summarize Failures = count(),\n            LastSeen = max(TimeGenerated),\n            Credentials = make_set(FederatedCredentialId, 5),\n            CredentialTypes = make_set(ClientCredentialType, 5),\n            IPs = make_set(IPAddress, 10)\n          by AppId, ServicePrincipalName\n| sort by Failures desc"
    }
  ],
  "kqlSectionText": "Which table 700226 lands in is undocumented. Our reading: the app registration whose credential was used is the one signing in, so `AADServicePrincipalSignInLogs` is the likely place. Check with a union first:\n\n```kusto\nunion withsource=SourceTable\n    SigninLogs,\n    AADNonInteractiveUserSignInLogs,\n    AADServicePrincipalSignInLogs,\n    AADManagedIdentitySignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700226\" or ResultSignature == \"700226\"\n| summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable\n```\n\nThe filter covers both columns because the tables document them differently: in `SigninLogs`, `ResultType` *\"provides the 5-6 digit error code\"*, while in `AADServicePrincipalSignInLogs` it is described as *\"Success or Failure\"* and `ResultSignature` as *\"the error code, if any, for the sign-in operation\"*.\n\nWhich app and which credential:\n\n```kusto\nAADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700226\" or ResultSignature == \"700226\"\n| summarize Failures = count(),\n            LastSeen = max(TimeGenerated),\n            Credentials = make_set(FederatedCredentialId, 5),\n            CredentialTypes = make_set(ClientCredentialType, 5),\n            IPs = make_set(IPAddress, 10)\n          by AppId, ServicePrincipalName\n| sort by Failures desc\n```\n\n`FederatedCredentialId` is documented as *\"Th identifier of an application's federated identity credential if a federated identity credential was used to sign in\"* (Microsoft's typo). Whether it is populated on a refusal is not documented, so confirm on a row of your own.",
  "fix": {
    "short": "Present a user-assigned managed identity token, with the credential subject set to that managed identity Object (Principal) ID in the same tenant. To let one app registration call another, use a client secret, a certificate, or on-behalf-of instead.",
    "steps": "**For developers:**\n1. If the workload runs on Azure, give it a **user-assigned managed identity** and present that identity's token. Set the credential's subject to the managed identity's **Object (Principal) ID**, exactly as Microsoft's page requires, and keep both objects in the same tenant.\n2. If the caller is an app registration and not a managed identity, stop using the Entra issuer. Use a client secret or a certificate credential on that app, or on-behalf-of when you are acting for a signed-in user.\n3. If the caller is outside Azure, use its own provider as the issuer: GitHub, Kubernetes or any OIDC provider that signs with RS256. Microsoft's restrictions page: *\"Only issuers that provide tokens signed using the RS256 algorithm are supported for token exchange using workload identity federation.\"*\n\n**For admins:**\n1. Check the federated credential's subject. It must be a user-assigned managed identity's Object (Principal) ID, not an app's service principal object ID.\n2. Both objects must be in the same tenant. Microsoft: *\"Both the Microsoft Entra app and managed identity must belong to the same tenant.\"*\n3. If you did not expect an Entra-issuer credential on this app, review who added it and why, in the audit log."
  },
  "labReproduced": {
    "date": "2026-10-30",
    "method": "Client-credentials token request with a federated identity credential, against a lab tenant",
    "scenario": "Federated credential matches",
    "message": "AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer.",
    "logCaptured": null,
    "kqlTested": null
  },
  "labSectionText": "On 30 October 2026 an automated lab run configured a federated identity credential on an app registration, using the lab tenant itself as the issuer (`https://login.microsoftonline.com/<tenant id>/v2.0`), and presented a normal app token in a client-credentials request. The run expected a token, because the credential's issuer, subject and audience were the ones the presented token carried. Entra returned:\n\n> AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer.\n\nThe run calls this scenario \"Federated credential matches\", and that is what makes the code useful: in the same run a mismatch on one of the three values gave [700211](https://brambrinkmeier.com/entra/aadsts/700211/), [700213](https://brambrinkmeier.com/entra/aadsts/700213/) or [7002121](https://brambrinkmeier.com/entra/aadsts/7002121/). 700226 is what Entra returns when those three match and the token is still the wrong kind. The lab did not test the supported arrangement, so it confirms the refusal, not that a managed identity token would have been accepted.\n\nNo sign-in log row was captured. 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 matches",
      "expected": "success",
      "got": "700226",
      "matchedExpectation": false,
      "message": "AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer."
    },
    {
      "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 matches",
      "expected": "success",
      "got": "700226",
      "matchedExpectation": false,
      "message": "AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer."
    },
    {
      "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 matches",
      "expected": "success",
      "got": "700226",
      "matchedExpectation": false,
      "message": "AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer."
    },
    {
      "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 matches",
      "expected": "success",
      "got": "700226",
      "matchedExpectation": false,
      "message": "AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer."
    },
    {
      "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 matches",
      "expected": "success",
      "got": "700226",
      "matchedExpectation": false,
      "message": "AADSTS700226: Only MSI tokens may be used as Federated Identity Credentials for AAD issuer."
    }
  ],
  "verification": "lab-reproduced",
  "related": [
    "70025",
    "700211",
    "700213",
    "7002121",
    "700212"
  ],
  "coveredBy": [],
  "sources": [
    {
      "title": "Microsoft Entra authentication and authorization error codes",
      "url": "https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes"
    },
    {
      "title": "Configure an application to trust a managed identity",
      "url": "https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-config-app-trust-managed-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": "Overview of federated identity credentials (Microsoft Graph)",
      "url": "https://learn.microsoft.com/en-us/graph/api/resources/federatedidentitycredentials-overview"
    },
    {
      "title": "Experimenting with Entra cross-tenant application Federated Identity Credential trust to Managed Identity (GitHub)",
      "url": "https://github.com/arsenvlad/entra-cross-tenant-app-fic-managed-identity"
    },
    {
      "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, \"AADSTS700226: Only managed identity tokens work with the Entra ID issuer (fix)\", https://brambrinkmeier.com/entra/aadsts/700226/ (CC BY 4.0)",
  "microsoftErrorLookup": "https://login.microsoftonline.com/error?code=700226"
}
