{
  "schemaVersion": "1.0",
  "code": "70025",
  "name": null,
  "title": "AADSTS70025: App has no federated identity credentials (fix)",
  "url": "https://brambrinkmeier.com/entra/aadsts/70025/",
  "alternates": {
    "markdown": "https://brambrinkmeier.com/entra/aadsts/70025.md",
    "json": "https://brambrinkmeier.com/api/aadsts/70025.json",
    "html": "https://brambrinkmeier.com/entra/aadsts/70025/"
  },
  "description": "AADSTS70025: an external token was sent for an app or managed identity with no federated identity credentials. Add one or fix the client ID. KQL.",
  "summary": "AADSTS70025 means a workload presented an external token for an app registration or managed identity that has no federated identity credentials at all. Usually the credential was never created, was deleted, or the pipeline points at the wrong client ID. Users also report it when a certificate assertion was expected. 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 AADSTS70025 (checked 30 October 2026). Microsoft's Azure DevOps troubleshooting page does:\n\n> **AADSTS70025: Client application has no configured federated identity credentials**\n> Make sure federated credentials are configured on the App registration or Managed Identity.\n\nWith workload identity federation, the workload sends a token from its own provider (GitHub, Azure DevOps, Kubernetes) as `client_assertion`, and Entra compares it with the federated identity credentials on the app or user-assigned managed identity named by the client ID. 70025 means that list is empty.\n\nOur reading: this is the step before the matching codes. If at least one credential exists but none matches, you get [70021](https://brambrinkmeier.com/entra/aadsts/70021/), [700211](https://brambrinkmeier.com/entra/aadsts/700211/) (issuer), [700212](https://brambrinkmeier.com/entra/aadsts/700212/) (audience), [700213](https://brambrinkmeier.com/entra/aadsts/700213/) (subject) or [7002138](https://brambrinkmeier.com/entra/aadsts/7002138/) (subject case). If the client ID doesn't exist in the tenant at all, you get [700016](https://brambrinkmeier.com/entra/aadsts/700016/) instead.\n\nUsers also report 70025 in a case Microsoft doesn't describe. On Microsoft Q&A, a user signing in with a **certificate** (a self-signed JWT sent as `client_assertion`, not federation) got *\"AADSTS70025: Client application has no configured federated identity credentials.\"* A second user reported the same with a certificate and a JWT assertion built in Python. The thread doesn't confirm a cause. Our reading, untested: Entra decided the assertion was an external token rather than a certificate assertion, so it looked for federated credentials. If you hit this with a certificate, check that the certificate is uploaded to the same app the client ID names, and how your library builds the assertion.",
  "sections": [
    {
      "heading": "What does AADSTS70025 mean?",
      "text": "Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS70025 (checked 30 October 2026). Microsoft's Azure DevOps troubleshooting page does:\n\n> **AADSTS70025: Client application has no configured federated identity credentials**\n> Make sure federated credentials are configured on the App registration or Managed Identity.\n\nWith workload identity federation, the workload sends a token from its own provider (GitHub, Azure DevOps, Kubernetes) as `client_assertion`, and Entra compares it with the federated identity credentials on the app or user-assigned managed identity named by the client ID. 70025 means that list is empty.\n\nOur reading: this is the step before the matching codes. If at least one credential exists but none matches, you get [70021](https://brambrinkmeier.com/entra/aadsts/70021/), [700211](https://brambrinkmeier.com/entra/aadsts/700211/) (issuer), [700212](https://brambrinkmeier.com/entra/aadsts/700212/) (audience), [700213](https://brambrinkmeier.com/entra/aadsts/700213/) (subject) or [7002138](https://brambrinkmeier.com/entra/aadsts/7002138/) (subject case). If the client ID doesn't exist in the tenant at all, you get [700016](https://brambrinkmeier.com/entra/aadsts/700016/) instead.\n\nUsers also report 70025 in a case Microsoft doesn't describe. On Microsoft Q&A, a user signing in with a **certificate** (a self-signed JWT sent as `client_assertion`, not federation) got *\"AADSTS70025: Client application has no configured federated identity credentials.\"* A second user reported the same with a certificate and a JWT assertion built in Python. The thread doesn't confirm a cause. Our reading, untested: Entra decided the assertion was an external token rather than a certificate assertion, so it looked for federated credentials. If you hit this with a certificate, check that the certificate is uploaded to the same app the client ID names, and how your library builds the assertion."
    },
    {
      "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 **no federated credential on the target app at all**, Entra returned `AADSTS70025`:\n\n> AADSTS70025: The client '<app id>'(<app name>) has no configured federated identity credentials.\n\nThe message names the client ID and the app's display name, so you can tell straight away which registration is missing the credential. This is the code you get when the credential was never created, or was created on a different app than the one in the request.\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": "No.\n\n| Pattern | Likely meaning |\n|---|---|\n| A new pipeline or workflow fails on its first run | The federated credential was never created on this app or managed identity. |\n| A pipeline points at a different app than the one you configured | The client ID in the pipeline or secret is another app registration with no credentials. In AL-Go issue 1147, a preview build of the tool read its credentials from a different GitHub secret than its docs said, and the maintainer called it a bug. |\n| It worked before and now fails | Someone deleted the app's last federated credential, or the pipeline now targets another app. Check the audit log (below). |\n| A certificate-based app fails with 70025 | Users report this. The cause is unconfirmed; see above. |"
    },
    {
      "heading": "How do I find it in my logs (KQL)?",
      "text": "Microsoft doesn't document which sign-in table 70025 lands in. App registration failures probably land in `AADServicePrincipalSignInLogs`; Microsoft says managed identity sign-ins are in the managed identity sign-in log *\"only\"*, so a user-assigned managed identity may log there instead. Check:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs, AADManagedIdentitySignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"70025\" or ResultSignature == \"70025\"\n| summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable\n```\n\nFailures per app. `ClientCredentialType` is documented as *\"The type of client credential used. Examples include client assertion, client secret, etc.\"* Seeing which type Entra recorded may help with the certificate case; that it is filled in on a failure is our assumption:\n\n```kusto\nAADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"70025\" or ResultSignature == \"70025\"\n| summarize Failures = count(),\n            FirstSeen = min(TimeGenerated),\n            LastSeen = max(TimeGenerated),\n            CredentialTypes = make_set(ClientCredentialType, 5),\n            IPs = make_set(IPAddress, 10)\n          by AppId, ServicePrincipalName\n| sort by Failures desc\n```\n\nIf the app had a credential before, look for its removal. A third-party write-up (trackr.live) reports that federated credential changes on an app registration log as `Update application` with a modified property `FederatedIdentityCredentials`; Microsoft doesn't document that name on the pages we checked:\n\n```kusto\nAuditLogs\n| where TimeGenerated > ago(30d)\n| where OperationName == \"Update application\"\n| mv-expand Target = TargetResources\n| mv-expand Prop = Target.modifiedProperties\n| where tostring(Prop.displayName) == \"FederatedIdentityCredentials\"\n| project TimeGenerated,\n          App = tostring(Target.displayName),\n          Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)),\n          OldValue = tostring(Prop.oldValue),\n          NewValue = tostring(Prop.newValue)\n```\n\nThe same write-up says changes on a user-assigned managed identity are Azure Resource Manager writes and appear in the Azure activity log, not the Entra audit log."
    },
    {
      "heading": "How do I fix AADSTS70025?",
      "text": "**For developers and pipeline owners:**\n1. Check which client ID the workload sends, and that it is the app or managed identity you configured.\n2. If you meant to use a certificate or secret, check the tool really sends that. In AL-Go issue 1147 the user's workaround was to go back from the preview to the `@main` version of the tool.\n\n**For admins:**\n1. Add a federated identity credential on that app registration (**Certificates & secrets** > **Federated credentials**) or on the user-assigned managed identity. Microsoft's create-trust page lists the issuer and subject values for GitHub, Kubernetes and other providers.\n2. Wait before the first run. Microsoft's restrictions page says a new credential takes time to propagate and early requests can fail with [70021](https://brambrinkmeier.com/entra/aadsts/70021/).\n3. If a credential was deleted and nobody meant to, find out who did it from the audit log before recreating it."
    }
  ],
  "microsoftWording": {
    "text": "**AADSTS70025: Client application has no configured federated identity credentials**\nMake sure federated credentials are configured on the App registration or Managed Identity.",
    "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": "No.\n\n| Pattern | Likely meaning |\n|---|---|\n| A new pipeline or workflow fails on its first run | The federated credential was never created on this app or managed identity. |\n| A pipeline points at a different app than the one you configured | The client ID in the pipeline or secret is another app registration with no credentials. In AL-Go issue 1147, a preview build of the tool read its credentials from a different GitHub secret than its docs said, and the maintainer called it a bug. |\n| It worked before and now fails | Someone deleted the app's last federated credential, or the pipeline now targets another app. Check the audit log (below). |\n| A certificate-based app fails with 70025 | Users report this. The cause is unconfirmed; see above. |",
    "conditionalAccess": null
  },
  "kql": [
    {
      "title": null,
      "leadIn": "Microsoft doesn't document which sign-in table 70025 lands in. App registration failures probably land in `AADServicePrincipalSignInLogs`; Microsoft says managed identity sign-ins are in the managed identity sign-in log *\"only\"*, so a user-assigned managed identity may log there instead. Check:",
      "query": "union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs, AADManagedIdentitySignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"70025\" or ResultSignature == \"70025\"\n| summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable"
    },
    {
      "title": null,
      "leadIn": "Failures per app. `ClientCredentialType` is documented as *\"The type of client credential used. Examples include client assertion, client secret, etc.\"* Seeing which type Entra recorded may help with the certificate case; that it is filled in on a failure is our assumption:",
      "query": "AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"70025\" or ResultSignature == \"70025\"\n| summarize Failures = count(),\n            FirstSeen = min(TimeGenerated),\n            LastSeen = max(TimeGenerated),\n            CredentialTypes = make_set(ClientCredentialType, 5),\n            IPs = make_set(IPAddress, 10)\n          by AppId, ServicePrincipalName\n| sort by Failures desc"
    },
    {
      "title": null,
      "leadIn": "If the app had a credential before, look for its removal. A third-party write-up (trackr.live) reports that federated credential changes on an app registration log as `Update application` with a modified property `FederatedIdentityCredentials`; Microsoft doesn't document that name on the pages we checked:",
      "query": "AuditLogs\n| where TimeGenerated > ago(30d)\n| where OperationName == \"Update application\"\n| mv-expand Target = TargetResources\n| mv-expand Prop = Target.modifiedProperties\n| where tostring(Prop.displayName) == \"FederatedIdentityCredentials\"\n| project TimeGenerated,\n          App = tostring(Target.displayName),\n          Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)),\n          OldValue = tostring(Prop.oldValue),\n          NewValue = tostring(Prop.newValue)"
    }
  ],
  "kqlSectionText": "Microsoft doesn't document which sign-in table 70025 lands in. App registration failures probably land in `AADServicePrincipalSignInLogs`; Microsoft says managed identity sign-ins are in the managed identity sign-in log *\"only\"*, so a user-assigned managed identity may log there instead. Check:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs, AADManagedIdentitySignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"70025\" or ResultSignature == \"70025\"\n| summarize Rows = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceTable\n```\n\nFailures per app. `ClientCredentialType` is documented as *\"The type of client credential used. Examples include client assertion, client secret, etc.\"* Seeing which type Entra recorded may help with the certificate case; that it is filled in on a failure is our assumption:\n\n```kusto\nAADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"70025\" or ResultSignature == \"70025\"\n| summarize Failures = count(),\n            FirstSeen = min(TimeGenerated),\n            LastSeen = max(TimeGenerated),\n            CredentialTypes = make_set(ClientCredentialType, 5),\n            IPs = make_set(IPAddress, 10)\n          by AppId, ServicePrincipalName\n| sort by Failures desc\n```\n\nIf the app had a credential before, look for its removal. A third-party write-up (trackr.live) reports that federated credential changes on an app registration log as `Update application` with a modified property `FederatedIdentityCredentials`; Microsoft doesn't document that name on the pages we checked:\n\n```kusto\nAuditLogs\n| where TimeGenerated > ago(30d)\n| where OperationName == \"Update application\"\n| mv-expand Target = TargetResources\n| mv-expand Prop = Target.modifiedProperties\n| where tostring(Prop.displayName) == \"FederatedIdentityCredentials\"\n| project TimeGenerated,\n          App = tostring(Target.displayName),\n          Actor = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName)),\n          OldValue = tostring(Prop.oldValue),\n          NewValue = tostring(Prop.newValue)\n```\n\nThe same write-up says changes on a user-assigned managed identity are Azure Resource Manager writes and appear in the Azure activity log, not the Entra audit log.",
  "fix": {
    "short": "Developer: check that the workload sends the client ID of the app or managed identity you configured. Admin: add a federated identity credential on it (Certificates & secrets > Federated credentials), then wait for it to propagate before the first run.",
    "steps": "**For developers and pipeline owners:**\n1. Check which client ID the workload sends, and that it is the app or managed identity you configured.\n2. If you meant to use a certificate or secret, check the tool really sends that. In AL-Go issue 1147 the user's workaround was to go back from the preview to the `@main` version of the tool.\n\n**For admins:**\n1. Add a federated identity credential on that app registration (**Certificates & secrets** > **Federated credentials**) or on the user-assigned managed identity. Microsoft's create-trust page lists the issuer and subject values for GitHub, Kubernetes and other providers.\n2. Wait before the first run. Microsoft's restrictions page says a new credential takes time to propagate and early requests can fail with [70021](https://brambrinkmeier.com/entra/aadsts/70021/).\n3. If a credential was deleted and nobody meant to, find out who did it from the audit log before recreating it."
  },
  "labReproduced": {
    "date": "2026-10-30",
    "method": "Client-credentials token request with a federated identity credential, against a lab tenant",
    "scenario": "Federated credential: no credential configured at all",
    "message": "AADSTS70025: The client '<app id>'(<app name>) has no configured federated identity credentials.",
    "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 **no federated credential on the target app at all**, Entra returned `AADSTS70025`:\n\n> AADSTS70025: The client '<app id>'(<app name>) has no configured federated identity credentials.\n\nThe message names the client ID and the app's display name, so you can tell straight away which registration is missing the credential. This is the code you get when the credential was never created, or was created on a different app than the one in the request.\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: no credential configured at all",
      "expected": "70025",
      "got": "70025",
      "matchedExpectation": true,
      "message": "AADSTS70025: The client '{app-id}'(lab-fic-target-41136574530) has no configured federated identity credentials."
    },
    {
      "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: no credential configured at all",
      "expected": "70025",
      "got": "70025",
      "matchedExpectation": true,
      "message": "AADSTS70025: The client '{app-id}'(lab-fic-target-41139925607) has no configured federated identity credentials."
    },
    {
      "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: no credential configured at all",
      "expected": "70025",
      "got": "70025",
      "matchedExpectation": true,
      "message": "AADSTS70025: The client '{app-id}'(lab-fic-target-41143330001) has no configured federated identity credentials."
    },
    {
      "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: no credential configured at all",
      "expected": "70025",
      "got": "70025",
      "matchedExpectation": true,
      "message": "AADSTS70025: The client '{app-id}'(lab-fic-target-41146039117) has no configured federated identity credentials."
    },
    {
      "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: no credential configured at all",
      "expected": "70025",
      "got": "70025",
      "matchedExpectation": true,
      "message": "AADSTS70025: The client '{app-id}'(lab-fic-target-41150019626) has no configured federated identity credentials."
    }
  ],
  "verification": "lab-reproduced",
  "related": [
    "70021",
    "700211",
    "700212",
    "700213",
    "7002138",
    "700016",
    "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": "Why am I receiving this error AADSTS70025 (Microsoft Q&A)",
      "url": "https://learn.microsoft.com/en-us/answers/questions/2071328/why-am-i-receiving-this-error-aadsts70025-client-a"
    },
    {
      "title": "AL-Go issue 1147 (GitHub)",
      "url": "https://github.com/microsoft/AL-Go/issues/1147"
    },
    {
      "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": "Important considerations and restrictions for federated identity credentials",
      "url": "https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-considerations"
    },
    {
      "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"
    },
    {
      "title": "A Federated Identity Credential Adds No Secret (trackr.live, third-party)",
      "url": "https://www.trackr.live/?p=1229"
    }
  ],
  "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, \"AADSTS70025: App has no federated identity credentials (fix)\", https://brambrinkmeier.com/entra/aadsts/70025/ (CC BY 4.0)",
  "microsoftErrorLookup": "https://login.microsoftonline.com/error?code=70025"
}
