Teams App / Bot 'Unauthorized' error when responding to an activity

Weston Boone 20 Reputation points
2025-10-31T23:45:29.9166667+00:00

Goal:

Create a teams app / bot for my department that can process requests (from DMs or channels), respond to them, and store the conversation context externally so that proactive messages can be sent when events happen in the future.
Current error:

[on_turn_error] unhandled error: Operation returned an invalid status code 'Unauthorized'
Traceback (most recent call last):
  File "C:\source\teamsapp\.venv\Lib\site-packages\botbuilder\core\bot_adapter.py", line 174, in run_pipeline
    return await self._middleware.receive_activity_with_status(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Testing Context:

  • Single Tenant Azure Bot has been created
    • currently sending requests to local code via ngrok
    • Teams channel has been added
  • Teams app manifest has been created, uploaded, and approved in my org
    • Messaging the app invokes my local code
  • Azure Entra App Registration
    • Authentication: Any Microsoft Entra ID tenant - Multitenant
      • The Single tenant option caused an error about not finding the client (app) id and i think that was because it was looking in some global bot framework catalogue
    • API Permissions: Microsoft Graph -> Delegated Permisions -> Channel.ReadBasic.All, ChannelMember.Read.All, Chat.Create, Chat.ReadBasic.WhereInstalled, Chat.ReadWrite.WhereInstalled
      • All permissions have been granted admin consent
  • Local code is currently hardcoding app id/password
    • Code is invoked as expected, but on sending an activity back to the conversation the pasted Unauthorized error is thrown
    • When testing against agentplayground locally with no app id/password set responding to a request was working, but i never got the proactive message bit to function

Questions/Concerns/Disclaimers:

  • I am drowning a bit in deprecated/renamed libraries and the general abstractions being forced by botframework so i'm sure i have some pretty obvious errors in my setup but am having a hard time determining what to search. Have also never dabbled in the Azure end of things
  • It seems like i would want the api permissions for graph to be delegated and not under the running user for my use case, but i don't see any that look like they would allow Channel messaging? Are these 'api permissions' actually needed for the bot to respond? Are they needed for the proactive messaging?
  • In the manifest.json under bots[0]['scopes'] i have ['personal','groupChat','team'] I assume those somehow translate into permissions when the app is installed in Teams ( i don't have Teams admin access). Are they related at all to the 'api permissions' in the registered app?
  • What is the relationship between the Azure Bot being 'Single tenant' and the App registration -> Authentication being Multitenant?
  • Should i be passing the tenant id into the Adapter config settings? It didn't seem to make any difference that i noticed:
      AUTH_CONFIG = AuthenticationConfiguration(tenant_id=CONFIG.TENANT_ID)
      SETTINGS = BotFrameworkAdapterSettings(CONFIG.APP_ID, CONFIG.APP_PASSWORD, auth_configuration=AUTH_CONFIG)
      ADAPTER = BotFrameworkAdapter(SETTINGS)
    

Let me know if any additional information would be helpful and thanks in advance.

Microsoft Teams | Development
Microsoft Teams | Development
Building, integrating, or customizing apps and workflows within Microsoft Teams using developer tools and APIs
{count} votes

Answer recommended by moderator
  1. Weston Boone 20 Reputation points
    2025-11-03T17:58:52.91+00:00

    I got past my immediate errors with a combination of two things:

    • Aligning the bot service and app registration to Single Tenant authentication
    • updating the adapter instantiation and process function to match what i was seeing on less deprecated code examples. Under the covers I'm sure this is doing something similar to creating the AUTH_CONFIG with the tenant id, but i haven't gone through enough of the code to know what exactly is the difference yet.

    Not working:

    from botframework.connector.auth import AuthenticationConfiguration
    CONFIG = DefaultConfig()
    AUTH_CONFIG = AuthenticationConfiguration(tenant_id="YOUR_TENANT_ID")
    SETTINGS = BotFrameworkAdapterSettings(app_id="YOUR_APP_ID", app_password="YOUR_APP_PASSWORD", auth_configuration=AUTH_CONFIG)
    ADAPTER = BotFrameworkAdapter(SETTINGS)
    

    Working (including the messages def because it is small and i had to tweak that to work with the CloudAdapter wrapper):

    Config has

    class DefaultConfig:
        """ Bot Configuration """
        PORT = 3978
        APP_ID = os.environ.get("MicrosoftAppId", "<app id>")
        APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "<app password>")
        APP_TYPE = os.environ.get("MicrosoftAppType", "SingleTenant")
        APP_TENANTID = os.environ.get('MicrosoftTenantId','<tenant id>')
    
    from botbuilder.integration.aiohttp import CloudAdapter, ConfigurationBotFrameworkAuthentication
    CONFIG = DefaultConfig()
    ADAPTER = CloudAdapter(ConfigurationBotFrameworkAuthentication(CONFIG))
    
    async def messages(req: Request) -> Response:
       return await ADAPTER.process(req, BOT)
    

1 additional answer

Sort by: Most helpful
  1. Jack-Bu 5,485 Reputation points Microsoft External Staff Moderator
    2025-11-01T10:22:52.4733333+00:00

    Dear Weston Boone

    Thank you for reaching to Microsoft Q&A regarding the "Unauthorized" error when responding to activities in your Teams bot. Based on a thorough review of similar cases and your described configuration, the error likely stems from a mismatch in tenant settings or authentication credentials. Your Azure Bot is single-tenant, but the Entra ID app registration was initially set to multitenant, which can cause authentication failures. Additionally, Microsoft's deprecation of new multi-tenant bots (effective July 31, 2025) may be impacting hybrid setups. Here something you can try to fix this:

    1. Recreate Resources for Consistency: Delete and recreate your Entra ID app registration as single-tenant (Accounts in this organizational directory only). Then, create a new single-tenant Azure Bot using this existing app registration. Generate a fresh app password.
    2. Update Code Snippet:
         from botframework.connector.auth import AuthenticationConfiguration
         AUTH_CONFIG = AuthenticationConfiguration(tenant_id="YOUR_TENANT_ID")
         SETTINGS = BotFrameworkAdapterSettings(app_id="YOUR_APP_ID", app_password="YOUR_APP_PASSWORD", auth_configuration=AUTH_CONFIG)
         ADAPTER = BotFrameworkAdapter(SETTINGS)
      
    3. Test Incrementally: Start with a minimal echo bot in the emulator, then test in Teams. Enable adapter logging for detailed errors. Check Azure Bot data residency (prefer Global if possible).
    4. Further Checks: Verify ngrok endpoint in Azure Bot config, regenerate credentials if needed, and monitor for region-specific issues.

    Hope this helps.


    If the answer is helpful, please click "Accept Answer" 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. 


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.