App role missing on service principal although present on app registration; Application permissions disabled and admin consent fails

Sam Wheat 506 Reputation points
2026-10-11T19:34:47.1166667+00:00

Summary

An app role defined on an app registration was never synchronized to the

corresponding service principal in the same tenant. As a result, the portal's

"Application permissions" option was disabled for that API, and admin consent

failed. Deleting and recreating the service principal resolved it.

Environment

  • Tenant: (6ae31a63-05b8-4d44-93c5-4ad9e370efe0), possibly an External ID tenant
  • Signed in as a guest account (outlook.com account) via the Entra admin center
  • API app registration: Application (client) ID: c1cf156a-e076-4a98-9282-df0f849396d8 Created: 2026-09-29
  • App role on the app registration: id 17e49161-1564-4f76-aa3e-e51aa8699779, value "DaemonAppRole", allowedMemberTypes ["Application"], isEnabled true
  • App manifest has servicePrincipalLockConfiguration enabled (isEnabled: true, allProperties: true)

Steps to reproduce

  1. Create an API app registration and add app role "DaemonAppRole" (allowed member types: Applications, enabled).
  2. In a separate client app registration, go to API permissions > Add a permission > APIs my organization uses > [API app].
  3. The "Application permissions" option is disabled. <<< This is the problem
  4. Add the role manually to the client app's manifest (requiredResourceAccess, type "Role") and click "Grant admin consent".

Actual result

  • "Application permissions" button disabled in the portal.
  • Admin consent fails with: "Grant consent failed with error: Claim is invalid: 17e49161-1564-4f76-aa3e-e51aa8699779 does not exist on resource application c1cf156a-e076-4a98-9282-df0f849396d8. [vm1a55cLUjJqJY4EyESEpv]"

Expected result

The app role on the app registration appears on the service principal, so it

is offered as an application permission and consent succeeds.

Troubleshooting performed

  • Verified the app manifest: the role is correct, enabled, and member type is Application.
  • Verified the service principal exists in Enterprise applications and matches the app ID.
  • Disabled and re-enabled the app role: no effect.
  • Clicking "Managed application in local directory": no effect.

Resolution / workaround

Deleting the service principal (Enterprise applications > Properties >

Delete) and letting it be recreated fixed the problem. After that,

Application permissions was enabled and consent worked.

Impact

The app role could not be assigned until the service principal was

recreated. Nothing in the UI indicates the service principal is out of

sync, and re-saving the role does not trigger a resync.

Request

Please investigate why the service principal's appRoles were not updated

from the application object, and whether the guest-account, External ID

tenant type, or servicePrincipalLockConfiguration setting contributed.

Microsoft Security | Microsoft Entra | Microsoft Entra External ID
0 comments No comments

1 answer

Sort by: Newest
  1. David Broggy 6,801 Reputation points MVP
    2026-10-12T12:01:35.18+00:00

    Hi Sam,

    Your diagnosis is correct, and the error text is the confirmation. Consent is evaluated against the resource's service principal, not its application object. A service principal's appRoles collection consists of definitions inherited from the application plus any added directly to the service principal, and changes to an application object are reflected in its service principal in the application's home tenant. When that collection is missing the role, Grant admin consent fails exactly as you saw — "does not exist on resource application" really means "does not exist on that app's service principal in this tenant" — and the portal disables Application permissions because it has no Application-type roles to offer.

    A lower-impact fix than deleting the service principal

    appRoles is an updatable property on the service principal, so it can be repaired in place:

    GET https://graph.microsoft.com/v1.0/servicePrincipals(appId='c1cf156a-e076-4a98-9282-df0f849396d8')?$select=id,appId,appRoles
    
    PATCH https://graph.microsoft.com/v1.0/servicePrincipals/{sp-object-id}
    Content-Type: application/json
    
    { "appRoles": [ /* the full collection, including DaemonAppRole */ ] }
    

    appRoles is not nullable and PATCH replaces the collection, so send the complete set — read the application object's appRoles first and submit that. Permissions are Application.ReadWrite.All delegated (with the Application Administrator or Cloud Application Administrator role) or Application.ReadWrite.OwnedBy app-only. Note the documented caveat that updating a service principal can trigger a directory refresh which changes properties you did not include in the request, so re-read the object afterwards.

    This matters beyond your current case: deleting the service principal also discards its app role assignments, user and group assignments, single sign-on configuration and any credentials on it. That is acceptable on a two-week-old test registration and expensive on a production API.

    On your three hypotheses

    • servicePrincipalLockConfiguration — not the cause. App instance property lock protects a defined set of sensitive service principal properties: credentials with usage type Sign, credentials with usage type Verify, and tokenEncryptionKeyId. appRoles is not among them, and allProperties: true means all of those sensitive properties rather than literally every property. Worth knowing that the lock is enabled by default for new applications since June 2026, so it will show up on registrations where you did not set it — but it would not block an appRoles update.
    • Guest account in the Entra admin center — probably not the cause, but cheap to rule out. The one documented gotcha in this area is ownership: if the API application and the client application do not both have an owner, the API is not even listed when you add a permission. Confirm both registrations have an owner, then re-run the repro signed in as a member account holding Application Administrator to see whether the guest context is actually involved.
    • External ID tenant type — the variable worth isolating. Run the same four steps (create an API app, add an Application-type app role, create a client app, add the permission) in a workforce tenant using a member Application Administrator. If the role lands on the service principal there but not in the External ID tenant, you have a clean and reportable reproduction.

    Getting the behaviour investigated

    Microsoft Q&A does not route to the product group, so if you want the sync behaviour looked at rather than only worked around, raise it through a Microsoft support case — quote the correlation ID from the consent error, vm1a55cLUjJqJY4EyESEpv — or through the Entra feedback channel, attaching the reproduction above.

    One aside: the tenant ID, application ID and role GUID in your post are now public. That is fine for a disposable test tenant, but worth redacting if any of it maps to something real.

    Documentation

    I hope that helps!

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.