ChannelMessage.Read.All application permission returns 403 Forbidden

yamauchi 0 Reputation points
2026-10-25T07:10:25.8433333+00:00

Environment:

  • App: Azure Bot (client credentials flow)
  • Permission: ChannelMessage.Read.All (Application) - Admin consent granted
  • Channel: Standard channel in a Team
  • Bot is installed in the Team

Error:

403 Forbidden / code: "Forbidden" / message: "UnknownError"

API call:

GET /teams/{teamId}/channels/{channelId}/messages/{messageId}

All conditions appear to be met:

  • ChannelMessage.Read.All (Application) added and admin consent granted
  • teamId is Azure AD Group GUID (not thread ID)
  • Channel is a standard channel
  • Bot is installed in the Team

Does ChannelMessage.Read.All require additional Microsoft approval

beyond admin consent (Protected API)?

Microsoft Teams | Development
Microsoft Teams | Development

Building, integrating, or customizing apps and workflows within Microsoft Teams using developer tools and APIs

0 comments No comments

Answer recommended by moderator
yamauchi 0 Reputation points
2026-10-27T07:59:05.7433333+00:00

Hi @Teddie Dang

Thank you for your continued support throughout this thread.

I'm happy to report that the issue has been resolved.

Root cause: The 403 "UnknownError" was caused by a tenant mismatch — the Azure app registration was configured as single-tenant, while the Teams environment belonged to a different tenant. This prevented the app from authenticating correctly against the Microsoft Graph API, resulting in the 403 error even though ChannelMessage.Read.All and admin consent appeared to be correctly configured.

Resolution: We changed the app registration from single-tenant to multi-tenant in the Azure portal (Supported account types → "Accounts in any organizational directory"). After this change, the Graph API calls started returning 200 OK successfully.

I hope this helps anyone else who encounters the same 403 "UnknownError" despite having the correct permissions — a tenant mismatch can produce this error without any descriptive indication of the actual cause.

Thank you again for your assistance.

Was this answer helpful?


1 additional answer

Sort by: Newest
  1. Teddie Dang 1,970 Reputation points Independent Advisor
    2026-10-25T08:10:31.7266667+00:00

    Hi @yamauchi

    I tested this scenario in Postman using the client credentials flow and the ChannelMessage.Read.All (Application) permission, with admin consent granted.

    I successfully received 200 OK from the following Microsoft Graph endpoints:

    GET /teams/{teamId}/channels/{channelId}/messages

    GET /teams/{teamId}/channels/{channelId}/messages/{messageId}

    To list channels and obtain the Channel ID, I also temporarily added Channel.ReadBasic.All (Application) and granted admin consent. However, if you already know the Team ID, Channel ID, and Message ID, you do not need Channel.ReadBasic.All just to retrieve an individual message.

    I was able to retrieve an individual message successfully in Postman without requiring a separate Protected API approval step in my test environment. This test does not establish whether additional approval requirements apply to other tenants or configurations.

    I suggest testing the same individual-message endpoint in Postman using your app's client credentials flow and access token. If it returns 200 OK but your bot still receives 403 Forbidden, compare the bot's token, app registration, tenant, and actual Graph request with the successful Postman request to identify the difference.

    Was this answer helpful?

    1 person found 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.