Skip to content

AADSTS7000218: Client secret or assertion missing from the request (fix)

Short answer: AADSTS7000218 means a token request reached Microsoft Entra ID as a confidential client but carried no client secret and no client assertion. Usually the app forgot the credential, or it uses ROPC, device code or IWA while the app registration is still set to confidential. Low attack value. The fix is to send the credential or, only when it fits, allow public client flows.

Fix: Developer of a web app, API or daemon: send `client_secret` or a certificate-signed `client_assertion` in the token request. App on a user's device: register a Mobile and desktop redirect URI, or have an admin set Allow public client flows to Yes, only for a real public client. Full steps

At a glance
CodeAADSTS7000218
CategoryApp configuration
TypeFailure
Attack signalLow: usually configuration or user error
Microsoft lookuplogin.microsoftonline.com/error?code=7000218

Microsoft’s description:

The request body must contain the following parameter: ‘client_assertion’ or ‘client_secret’.

The reference table gives this code no PascalCase name.

A token request arrived for an app that Microsoft Entra ID treats as a confidential client, and it carried no proof of the app’s identity. Microsoft’s troubleshooting article says the request fails with invalid_client and that confidential clients must supply a client secret or a client assertion.

Two siblings help you tell the cases apart:

  • 7000215: “Invalid client secret is provided.” A secret was sent and it was wrong.
  • 7000222: “The provided client secret keys are expired.” The secret was right but expired.

So 7000218 means nothing was sent at all.

How Entra decides the client is confidential

Section titled “How Entra decides the client is confidential”

This is the part that catches most people. According to Microsoft’s troubleshooting article:

  1. If the request has a redirect URI, the platform type of that redirect URI decides. A Web redirect URI makes the app a confidential client. A Mobile and desktop applications redirect URI makes it a public client.
  2. If the request has no redirect URI (ROPC, device code, Integrated Windows Authentication), Entra uses the Allow public client flows setting on the app registration. Yes means public, No means confidential.

So a desktop tool that uses device code flow, registered with the default setting, gets 7000218 even though it was never meant to have a secret.

On 30 October 2026 an automated lab run created an app registration without public client flows enabled, then sent a password-grant (ROPC) request with no credential. Entra returned AADSTS7000218:

AADSTS7000218: The request body must contain the following parameter: ‘client_assertion’ or ‘client_secret’.

The same run also sent a client-credentials request with no credential, and that returned a different code, AADSTS7000216 (“‘client_assertion’, ‘client_secret’ or ‘request’ is required for the ‘client_credentials’ grant type”). So the code depends on the grant type: 7000218 comes from a user-credential flow, 7000216 from client credentials.

The sign-in log row isn’t captured yet; see how pages are checked.

In the lab tenant’s sign-in logs the row appears under User sign-ins (interactive), Status Failure, Conditional Access Not Applied, with the Application column naming the confidential app that sent the request without a credential.

Almost never. 7000218 is a configuration mismatch between the app and its registration. The request carried no credential, so it can’t have succeeded.

Pattern Likely meaning
7000218 for a new app during testing The developer hasn’t added the secret or certificate yet, or registered the wrong platform type.
7000218 for a desktop script or CLI tool using device code or ROPC The registration is confidential (public client flows set to No). Fix the registration or the flow.
7000218 for an app that worked yesterday Someone changed the redirect URI platform or the public client setting, or a deployment dropped the secret from its configuration. Check the audit log for Update application.
7000218 from an IP you don’t own, for your app ID Someone outside is trying your app ID without a credential. Our interpretation: they have the client ID, which is public by design, but not the secret. Low risk on its own.

Microsoft notes that “The client ID is a public value that identifies the application, while the client secret is a confidential value.” Knowing a client ID is not a compromise.

The real security question is the fix, not the error. See the admin steps below before switching an app to a public client.

Microsoft doesn’t document which sign-in table 7000218 lands in. Our reading: an app-only request (client credentials) would be a service principal sign-in, and a delegated request (device code, ROPC, authorization code) would be a user sign-in. Check where it lands in your workspace:

union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs
| where TimeGenerated > ago(7d)
| where ResultType == "7000218"
| summarize Rows = count(), Apps = dcount(AppId) by SourceTable

Which apps hit it, from where, and since when:

union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs
| where TimeGenerated > ago(30d)
| where ResultType == "7000218"
| summarize Rows = count(),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated),
IPs = make_set(IPAddress, 10),
Users = dcount(UserPrincipalName)
by AppId, AppDisplayName = coalesce(AppDisplayName, ServicePrincipalName)
| sort by Rows desc

If an app moved from 7000218 to success, check whether it got there by adding a secret or by being switched to a public client. The audit log shows the change to the app registration:

AuditLogs
| where TimeGenerated > ago(30d)
| where Category == "ApplicationManagement"
| where OperationName startswith "Update application"
| project TimeGenerated, OperationName, InitiatedBy, TargetResources
| sort by TimeGenerated desc

Microsoft’s audit activity reference lists both Update application and Update application - Certificates and secrets management in the ApplicationManagement category. The query uses startswith so it catches both; the exact punctuation in the stored OperationName may differ from the reference. TargetResources holds the changed properties, but which property names a public client switch writes isn’t documented, so read the rows rather than filter on them. Service principal rows are aggregated when the service principal, status, IP address and resource match, so row counts there are not request counts. ResultType is a string column, so compare it with "7000218".

For developers:

  1. If your app is a confidential client (web app, web API, daemon), send the credential. Add client_secret, or a client_assertion signed with a certificate, to the token request. Microsoft’s authorization code reference says the client secret “is required for web apps and web APIs, which can store the client_secret securely on the server side.”
  2. If your app runs on a user’s device (desktop, mobile, CLI, script), it is a public client and must not carry a secret. Microsoft: public clients “can’t be trusted to safely keep application secrets”. Register a Mobile and desktop applications redirect URI, or for flows without a redirect URI, ask an admin to turn on public client flows.
  3. To find out which flow your code uses, look at grant_type in the token request (in code or a Fiddler trace). Microsoft’s article lists password for ROPC, urn:ietf:params:oauth:grant-type:device_code for device code, authorization_code, client_credentials, and urn:ietf:params:oauth:grant-type:jwt-bearer for on-behalf-of.

For admins:

  1. For a confidential app, the fix is a credential, not a setting. Prefer a certificate or managed identity over a secret.
  2. Only for a real public client flow: in App registrations > the app > Authentication > Advanced settings, set Allow public client flows to Yes. Microsoft warns that this changes the client type from confidential to public, with security implications.
  3. Our reading of those implications, not Microsoft’s wording: once public client flows are on, anyone who knows the client ID can start ROPC or device code flows for that app without a secret. The client ID is public, so the secret no longer stands between an attacker and those flows. Don’t flip the setting just to make the error go away, and don’t flip it on an app that also uses a secret for server-side work.
  4. If you do allow public client flows, make sure MFA and Conditional Access cover the users who sign in through that app.

More: 90023, 90133, 700024, 1002016, 5002730, 7000216, 9002326, 9002327

Sources

  1. Microsoft Entra authentication and authorization error codes
  2. Error AADSTS7000218 when a confidential client application authenticates to Microsoft Entra ID
  3. Public client and confidential client applications
  4. Microsoft identity platform and OAuth 2.0 authorization code flow
  5. Microsoft Entra audit log categories and activities
  6. Service principal sign-ins