Calling 365 inbox using MS Graph API returns a bare 401 with an empty response body

Simon 0 Reputation points
2026-07-22T22:23:02.37+00:00

I'm trying to set up polling-based ingestion of a shared mailbox via Microsoft Graph delta queries, called from an Azure Function using its system-assigned managed identity — no client secret/cert, app-only (client credentials) auth. I have granted Mail.Read (application permission) directly to the function's service principal via Microsoft Graph PowerShell. Decoding the MI's issued JWT (via jwt.ms) confirms roles contains Mail.Read and appid matches the MI's Application ID. I created a mail-enabled security group and added the target mailbox. I applied this to the MI's appId so that it only had access to this one inbox. The function code gets a token using it's System Assigned Managed Identity for the context "https://graph.microsoft.com/.default", which is used as a bearer token to GET "https://graph.microsoft.com/v1.0/users/inbox@company/mailFolders/inbox/messages". This returns a 401 response with no body or WWW-Authenticate header.

The same token used with /users returns 403 with a proper structured body as expected since no user read permissions were granted. So the token is valid at least. I've tried from my local machine to see if there was a network related issue calling from azure, but I get the same response.

The mailbox is fully provisioned with a MS 365 Business Basic license. EwsEnabled / MAPIEnabled / OWAEnabled / ActiveSyncEnabled are all True at the mailbox level (Get-CASMailbox). I can send and receive email for this shared inbox using my work account.

Microsoft 365 and Office | Development | Other
0 comments No comments

1 answer

Sort by: Most helpful
  1. Michelle-N 20,645 Reputation points Microsoft External Staff Moderator
    2026-07-23T09:55:54.6166667+00:00

    Hi @Simon

    Based on the information you provided, I understand that you are setting up a polling-based ingestion workflow for a shared mailbox using Microsoft Graph delta queries via an Azure Function with a System-Assigned Managed Identity. Even though your JWT token contains the Mail.Read application permission and works as expected (returning a 403 on /users), calling the endpoint [https://graph.microsoft.com/v1.0/users/inbox@company/mailFolders/inbox/messages](https://graph.micr… consistently returns a bare 401 Unauthorized with no response body or WWW-Authenticate header.

    The bare 401 with an empty body is a classic symptom of an Application Access Policy denying access. When an Application Access Policy configured with AccessRight RestrictAccess is active and the calling application is either not allowed to access that specific mailbox, or if the policy has not fully propagated (or was created with the wrong ID), Microsoft Graph deliberately returns a silent 401 instead of a standard structured error payload.

    To resolve this issue, please try referring to the following troubleshooting steps:

    1. Test the Application Access Policy immediately

    Run the following PowerShell command via Exchange Online to verify the policy's evaluation:

    Connect-ExchangeOnlineTest-ApplicationAccessPolicy -Identity "******@company.com" -AppId "<Managed-Identity-Application-ID>"
    
    • Target outcome: You want to see AccessCheckResult : Granted.
    • If it returns Denied, the Application Access Policy is actively blocking your calls.
    1. Confirm you used the correct ID

    When creating an Application Access Policy for a System-Assigned Managed Identity, you must use the Application (Client) ID, not the Object ID of the Enterprise Application / Service Principal.

    You can verify the correct Client ID via:

    • Azure Portal: Function App $\rightarrow$ Identity $\rightarrow$ System assigned $\rightarrow$ Client ID
    • PowerShell / Graph: Inspecting the Service Principal’s appId property.
    1. Temporary isolation test

    To confirm whether the policy is indeed causing the block:

    1. Temporarily remove the Application Access Policy.
    2. Re-test the Microsoft Graph call.
    3. If the endpoint starts returning 200 OK, the policy configuration was the sole culprit.
    4. Carefully recreate the policy with the validated App ID and mail-enabled security group.
    5. Account for propagation delays

    After creating or updating an Application Access Policy, wait at least 30 to 60 minutes (Microsoft documentation notes that propagation can sometimes take over an hour in certain tenants). Re-run Test-ApplicationAccessPolicy periodically until it reflects Granted.

    1. Additional sanity checks
    • Group Type: Confirm that the group containing your mailbox is strictly a Mail-enabled Security Group (not a Microsoft 365 Group, Security Group, or Distribution List).
    • Group Membership: Verify that ******@company.com is explicitly added as a member of this Mail-enabled Security Group.
    • Admin Consent: Double-check that Admin Consent for Mail.Read was properly granted specifically for your Managed Identity's Application ID.

    Once the baseline /messages endpoint successfully returns a 200 OK, you can seamlessly switch to your delta query endpoint:

    GET https://graph.microsoft.com/v1.0/users/inbox@company/mailFolders/inbox/messages/delta
    

    Let me know how the Test-ApplicationAccessPolicy check goes.


    If the answer is helpful, please click "Yes" and kindly upvote it. If you have extra questions about this answer, please click ""Comment"".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    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.