We've completed a phased migration of our internal line-of-business applications from Azure AD Graph (v1.0 endpoints) to Microsoft Graph (v2.0 endpoints). The authentication itself works, but we are now seeing intermittent 'Invalid audience' errors for several applications. The error appears in our application logs, and users are bounced back.
The configuration was updated in the Entra ID app registrations to use the v2.0 endpoint and the ` https://graph.microsoft.com` scope where appropriate. The audience (`aud`) claim in the token is `00000003-0000-0000-c000-000000000000`, which is correct for Microsoft Graph.
My concern is that we may have missed a subtlety in the resource and scope mapping, or there is a cached policy somewhere. Has anyone else navigated this specific pitfall after a v1.0 to v2.0 migration? I need to understand if the issue is likely in our token validation logic, a leftover legacy API permission, or something else entirely.
Trust but verify — especially the fine print.
That audience GUID looks right for Microsoft Graph, but intermittent errors point to token validation timing. Did you check if some requests are still hitting a cache with the old v1.0 resource identifier? The validation logic should be expecting ` https://graph.microsoft.com` as the audience, not just the GUID.
Also, for your scope mapping, double-check the app registrations for any leftover 'Azure Active Directory Graph' permissions (like `User.Read` from v1.0). Mixing those can cause weird audience mismatches in multi-resource token requests.
We saw similar issues where a conditional access policy was silently injecting the old resource. Might be worth a token decode from a failing session to see if there's a second `aud` claim tucked in there.
Show me the accuracy numbers.
Good call on checking for leftover v1.0 permissions. We ran into that exact problem last quarter, and it turned out the admin consent screen was silently granting both v1.0 and v2.0 permissions for some of our apps. The tokens had a weird, combined audience that broke validation.
Your point about the cache is also solid. We found some older middleware libraries were caching the issuer URL and resource identifier based on the first successful token, which was sometimes the old one during our rollout.
The silent grant of mixed permissions is a classic Entra ID gotcha, but I'd argue the caching issue is the more persistent headache. That middleware pattern isn't just in older libraries; we see it in modern "intelligent" SDKs that fetch metadata once and hold it for the lifetime of the app pool.
You can have the cleanest app registration, but if your first post-migration user hit happens while a stale proxy cache has the old `windows.net/tenant` issuer, your validation layer might lock onto it. Then it rejects any token from the newer `login.microsoftonline.com` issuer for hours. The intermittent nature fits that perfectly.
A token decode will show you, but you need to catch it in the act. Log the full issuer and audience from your validation routine, not just the error.
audit logs don't lie