# AADSTS50146 fix: custom claims need an app signing key

Canonical: https://brambrinkmeier.com/entra/aadsts/50146/
By Bram Brinkmeier. JSON: https://brambrinkmeier.com/api/aadsts/50146.json

**Short answer:** AADSTS50146 means Microsoft Entra ID refused to issue a token because the app's claims were customized but the app hasn't accepted that: it has no app-specific signing key (or the key expired), and it doesn't set acceptMappedClaims. It usually starts right after someone adds a claim to an app. It is a configuration error and a deliberate safeguard. Low attack value.

**Fix:** Developer, single-tenant app: set `acceptMappedClaims` to `true` in the app manifest and use a verified-domain Application ID URI. Multitenant app: add a custom signing key to the service principal and validate tokens with `?appid=`. Expired key: renew it. User: contact the app owner.

| Field | Value |
|---|---|
| Code | AADSTS50146 |
| Microsoft name | MissingCustomSigningKey |
| Category | App configuration |
| Type | Configuration error |
| Attack signal | Low: usually configuration or user error |
| In Microsoft's error reference | Yes |
| Verification | documentation |
| Last updated | 2026-11-01 |

## What does AADSTS50146 mean?

Microsoft's description:

> **MissingCustomSigningKey**: This app is required to be configured with an app-specific signing key. It's either not configured with one, or the key has expired or isn't yet valid. Please contact the owner of the application.

The trigger is **claims customization**: someone changed which claims Entra ID puts in the app's tokens. Microsoft explains why that needs an extra step: *"Applications that receive tokens rely on claim values that can't be tampered with. When you modify the token contents through claims customization, these assumptions may no longer be correct. Applications must explicitly acknowledge that tokens have been modified."*

The app can acknowledge it in one of two ways:

- **A custom signing key** on the service principal. By default an app *"is using the Azure global sign-in key, which can't be used for customizing claims in tokens."*
- **`acceptMappedClaims` set to `true`** in the app manifest. This is for single-tenant apps only.

*"Without this, Microsoft Entra ID returns an AADSTS50146 error code."* The description also covers a custom key that exists but has expired or isn't valid yet.

## Is it an attack?

No. 50146 is the safeguard working. Microsoft's warning on the alternative shows what it protects against: *"Do not set the acceptMappedClaims property to true for multi-tenant apps, which can allow malicious actors to create claims-mapping policies for your app."*

Users report it after ordinary changes:

- In a Microsoft Q&A thread, a developer added the optional claim `onpremisessamaccountname` to a single-tenant app with a SPA and an API scope, and sign-in started failing with 50146.
- Auth0's knowledge base covers it on an Auth0 connection to Entra ID, where the token request fails with *"failed to obtain access token"*.

| Pattern | Likely meaning |
|---|---|
| One app, every user, starting right after a claim was added | Claims customization without a signing key or `acceptMappedClaims`. Configuration. |
| An app that worked for months starts failing for everyone | The custom signing key has expired. |
| A claims-mapping policy appears on an app nobody on your team changed | Not 50146 itself, but worth a look. Our interpretation: someone is changing what tokens for that app contain. |

## How do I find it in my logs (KQL)?

Microsoft doesn't document which sign-in table 50146 lands in. Check your workspace:

```kusto
union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs
| where TimeGenerated > ago(30d)
| where ResultType == "50146"
| summarize Rows = count(), Apps = dcount(AppId), FirstSeen = min(TimeGenerated) by SourceTable
```

Which apps fail and since when:

```kusto
union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(30d)
| where ResultType == "50146"
| summarize Rows = count(),
            Users = dcount(UserPrincipalName),
            FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated),
            Resources = make_set(ResourceDisplayName, 5)
          by AppDisplayName, AppId
| sort by Users desc
```

Recent policy and app changes, to find the change that started it. Microsoft lists **Add policy to service principal**, **Add policy to application** and **Update application** as audit activities. Our assumption: assigning a claims-mapping policy appears as one of the first two, and a manifest change as the third; Microsoft doesn't map them explicitly.

```kusto
AuditLogs
| where TimeGenerated > ago(30d)
| where Category == "ApplicationManagement"
| where OperationName in ("Add policy to service principal", "Add policy to application", "Update application")
| extend Target = tostring(TargetResources[0].displayName),
         ByUser = tostring(InitiatedBy.user.userPrincipalName)
| project TimeGenerated, OperationName, Target, ByUser, Result
| sort by TimeGenerated desc
```

`ResultType` is a **string** column, so compare it with `"50146"`.

## How do I fix AADSTS50146?

**For the user:** you can't fix this. As Microsoft's description says, contact the owner of the application.

**For developers, single-tenant app:**
1. In the app manifest, set `acceptMappedClaims` to `true`. Microsoft: *"Setting the property allows an application to use claims mapping without specifying a custom signing key."*
2. Set the **Application ID URI** to a verified domain of your tenant, for example `https://contoso.com/my-api`. If you don't, you trade 50146 for AADSTS501461: *"AcceptMappedClaims is only supported for a token audience matching the application GUID or an audience within the tenant's verified domains."* The Q&A thread above hit exactly this with an `api://<appid>` URI.

**For developers, multitenant app:**
1. Don't use `acceptMappedClaims`. Microsoft: *"For multitenant apps, a custom signing key should be used."*
2. Create a key from a certificate and add it to the **service principal**: the private key and public key as key credentials, and the password as a password credential, with matching `keyId` values. The private key must be in PKCS#12 format.
3. Validate tokens against the app's own keys. Apps with claims mapping *"must validate their token signing keys by appending `appid={client_id}` to their OpenID Connect metadata requests"*: `https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration?appid={client-id}`.

**For admins:**
1. Check the app's recent changes (third query). If a claim was added, the developer needs one of the two fixes above.
2. If the app already has a custom signing key, check whether it has expired. The description names an expired or not-yet-valid key as a cause. Replace it with a new certificate.
3. Some settings only work with a custom key. Microsoft says the **Issuer With Application ID** and **Audience Override** settings are *"ignored if a custom signing key isn't configured for the application."*

## Evidence

Not reproduced in the lab yet; the page is based on Microsoft's documentation.

## Sources

1. [Microsoft Entra authentication and authorization error codes](https://learn.microsoft.com/entra/identity-platform/reference-error-codes)
2. [Customize claims issued in the JSON web token (JWT) for enterprise applications](https://learn.microsoft.com/en-us/entra/identity-platform/jwt-claims-customization)
3. [Claims customization using a policy](https://learn.microsoft.com/entra/identity-platform/reference-claims-customization)
4. [Microsoft Entra audit log categories and activities](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities)
5. [After adding a new claim to an app I am getting AADSTS50146 (Microsoft Q&A, user report)](https://learn.microsoft.com/en-us/answers/questions/2180433/after-adding-a-new-claims-to-an-app-i-am-getting-t)
6. [Failed to obtain access token and error AADSTS50146 (Auth0 KB, user report)](https://support.auth0.com/center/s/article/microsoft-azure-ad-entra-id-failed-to-obtain-access-token-and-error-aadsts50146)

## License and citation

CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). 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.

Cite as: Bram Brinkmeier, "AADSTS50146 fix: custom claims need an app signing key", https://brambrinkmeier.com/entra/aadsts/50146/ (CC BY 4.0), last updated 2026-11-01.
