Share via

Graph API 401 Unauthorized for Guest Users on Shared Files (Works in Lab, Fails in Prod)

FabulousFab 41 Reputation points
2026-02-08T21:44:55.5233333+00:00

I have a web application (SPA) that accesses SharePoint Online files on behalf of a logged-in user (Delegated permissions). The application does not use a Service Principal for file access; it relies entirely on the user's context.

  • The User: An external Guest user (B2B) invited to the tenant.
  • The Action: The user logs in, and the app attempts to resolve a specific SharePoint sharing link (sent via "Specific People" sharing) using the Microsoft Graph API.
  • The Issue: The API call returns 401 Unauthorized (Code: accessDenied) in the Production tenant.
  • The Mystery: The exact same code, configuration, and user setup works perfectly in my Lab tenant. When opening the link directly - not through my web app, it works! I first have to confirm my email, click on 'Next', but then all is good, even through my web app. For a few hours before (probably a token) expires, that is...

The API Call I am using the /shares/ endpoint to resolve the sharing link: GET https://graph.microsoft.com/v1.0/shares/u!{encoded_url}/driveItem

Symptoms

Graph API: Returns 401 Unauthorized.

Graph /users Endpoint: GET /users also returns 401, even though the token has User.Read.All.

Graph /sites Endpoint: GET sites/id also returns 401.

Token Scopes: I have decoded the access token (scp claim) and it does contain the required scopes (Files.Read.All, Sites.Read.All, User.Read.All, etc.).

Admin Consent: In the Enterprise Application (Prod), the "Admin consent" tab is fully populated with all required permissions. The "User consent" tab is empty (likely due to tenant policy blocking user consent), but the Admin Grant is definitely there.

What I have tried (and ruled out)

Tenant Context: Confirmed the auth endpoint is using the correct hosting tenantId, not common or the user's home tenant.

Link Encoding:

  • Verified the base64 encoding logic is correct (the same link works if I log in as a Global Admin).

User Information List:

  • I always add the guest user with a script to the User Information List when the invite goes out.

Guest Settings:

  • Verified "Guest user access" in Entra ID (tried both "Limited" and "Restricted").
  • Verified "Cross-tenant access settings" (Inbound trust is set to allow All Applications).
  • Verified that the guest user is 'Active' and 'Accepted'

Enterprise App Config:

  • "Assignment Required" is set to No.
  • "Visible to users" is set to Yes.
  • I have forced "Grant Admin Consent" via the portal button.

Security Policies:

  • Conditional Access: The test user is exempted from all policies.
  • Security Defaults: Disabled (using CA).
  • SharePoint "Lockdown Mode": Disabled on the site collection.

User Setup:

  • User is definitely a Guest in both tenants.
  • User is explicitly named in the "Specific People" sharing link.
  • I confirmed the login hint/email matches the link target.

The Question Since the token has the correct scopes and the Admin Consent is granted, why is this Guest User still getting a 401 on both Graph and Native SharePoint calls in the Production tenant? Are there any hidden "directory-level" settings that would block a Guest's token even if the App has permission?

Any help would be appreciated.I have a web application (SPA) that accesses SharePoint Online files on behalf of a logged-in user (Delegated permissions). The application does not use a Service Principal for file access; it relies entirely on the user's context.

Microsoft 365 and Office | SharePoint | Development
{count} votes

Answer accepted by question author
  1. Matthew-P 11,565 Reputation points Microsoft External Staff Moderator
    2026-02-08T23:46:11.95+00:00

    Hi FabulousFab,

    Welcome to Microsoft Q&A Forum!  

    Thank you for the very detailed breakdown. I really appreciate the time and effort you have put into analyzing and narrowing down the behavior you are seeing. 

    Please note that this is a peer‑to‑peer forum, so we can only share observations and patterns seen in similar environments. We do not have visibility into, or the ability to confirm, internal tenant‑level enforcement or backend behavior on Microsoft’s side. 

    From my findings and experience with comparable scenarios, what you are observing does align with common differences between Lab and Production tenants. 

    In particular, your Lab tenant likely has: 

    • More permissive default guest access settings 
    • Automatic or implicit invitation redemption behavior 
    • Fewer directory‑level or SharePoint enforcement restrictions 

    Production tenants, by contrast, are almost always stricter by design. 

    One important distinction that often causes confusion is that invitation accepted does not necessarily mean invitation redeemed. 

    A guest user can be: 

    • Invited 
    • Accepted 
    • Active 

    and still not be fully redeemed for a specific SharePoint resource. 

    Until the guest redeems the invitation by opening the sharing link or invitation URL at least once: 

    • Authentication occurs only in the guest’s home tenant 
    • The access token is not backed by a resource‑tenant (SharePoint) sign‑in 
    • Directory‑backed and resource‑backed endpoints, including Microsoft Graph, may refuse access 

    This also explains why opening the sharing link once immediately resolves the issue. That interaction completes the resource‑level redemption and establishes the required SharePoint context. After that, delegated Graph calls succeed, typically until the SharePoint session expires. 

    At this point, I am not aware of a tenant‑level setting that fully bypasses this behavior when using Guest users together with “Specific People” sharing in Production environments. 

    If you would like deeper investigation or authoritative confirmation, I would recommend continuing the discussion through channels that are better suited for product‑level analysis, such as: 

    If I have misunderstood anything, or if you have any updates to share, please feel free to reach out at any time so we can gain additional insights together.


    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.  

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Erick Manga 75 Reputation points
    2026-02-08T22:10:40.7633333+00:00

    Re: Graph API 401 Unauthorized for Guest Users on Shared Files

    Hi @FabulousFab , Excellent breakdown of the problem. The fact that it works in Lab but not in Production, and that you mention needing to "confirm the email" before the app works, points to a tenant security setting in SharePoint/OneDrive that is blocking silent delegated authentication.

    Here are the 3 most likely causes in Production environments:

    1. Guest User "Validation Status"

    In strict Production environments, SharePoint requires guest users to validate their identity using a one-time password (OTP) sent to their email before allowing external APIs (like Graph) to access shared resources with "Specific People."

    Why the app fails: Your SPA tries to use the Graph token directly, but SharePoint marks the session as "not validated" for that specific resource. By manually opening it in the browser and clicking "Next," it creates a validated session cookie, which is why the app works "for a few hours" (until the SharePoint session expires).

    2. SharePoint "Limited Access User Provider" Mode

    Check if the "Limited access permissions blocking mode for external users" feature is enabled in Production.

    Check: Go to the SharePoint admin center > Site settings > Site collection features. If enabled, guests cannot use delegated applications to access files unless they have a license or very specific permissions.

    3. SharePoint Policy: "Require guests to sign in with the same account"

    In the SharePoint admin center (Policies > Sharing), review the advanced file and folder settings.

    If the "Allow guests to view content without signing in" option is disabled (common in Production), but the binding is set to "Specific People," Graph sometimes fails to resolve /shares/ if the UserType in the Entra ID does not exactly match the identity SharePoint expects.

    🛠️ What to try next:

    Change the link type: Try creating a "People in your organization" link (if the Guest is already in the directory) or a "People with existing access" link and see if the 401 error persists.

    Check the "SharePoint and OneDrive integration with Entra B2B": Run this command in SharePoint PowerShell: Get-SPOTenant | select EnableAzureADB2BIntegration. If this is True in Lab and False in Production, the behavior of guest tokens is radically different. Production should have this set to True for Graph to work correctly with guests.

    Review the Token Claims: Check if the token in Production has the Claim acrs. If a value related to MFA or terms of use appears, the Graph API will return a 401 error because the SPA doesn't know how to handle this additional security "challenge."

    References:

    Microsoft Learn: SharePoint and OneDrive integration with Azure AD B2B

    Microsoft Graph API Reference: Access shared DriveItems

    SharePoint Admin Documentation: External sharing overview

    Microsoft Graph Error Codes: 401 Unauthorized


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.