Microsoft Teams Bot Framework reference

Microsoft Teams bot error codes, explained one by one

24documented codes
7categories
2026-08-20last verified

Last verified against Microsoft Learn - Status codes from bot conversational APIs

A Microsoft Teams bot fails in three distinct layers, and the same symptom - the bot goes quiet - can come from any of them. The first layer is Microsoft Entra authentication: your bot exchanges its app ID and client secret for a token at login.microsoftonline.com, and failures there surface as AADSTS error codes in the token response (an expired secret, a wrong tenant, a mistyped app ID) before any message is ever sent. The second layer is the Bot Framework Connector API at smba.trafficmanager.net: your sends and replies come back with HTTP statuses and Teams-specific error codes such as BotDisabledByAdmin, ConversationBlockedByUser, or Throttled, documented in the conversational-API status table on Microsoft Learn. The third layer is your own messaging endpoint: when it times out, throws, or returns 5xx, the channel reports a 502 with "Failed to send activity: bot returned an error" - and in Teams the user usually sees nothing at all.

Knowing which layer produced the error is half the fix. Entra failures appear in your logs at startup or on the first outbound call and never reach Teams. Connector failures appear as ErrorResponseException (C# SDK) or a rejected promise carrying the HTTP status (Node SDK) when you call send, update, or delete. Endpoint failures appear in the Azure Bot resource's health blade and Application Insights, not in your send path. This page lists every status the conversational APIs document, plus the Entra codes that break bot authentication - each with the literal code and message, what actually causes it, and the ordered fix. For the ten most common not-responding scenarios walked end to end, see Microsoft Teams bot not responding; for the numeric ceilings behind the throttling entries, see Teams bot limits.

How to read a Teams error

Connector API errors arrive as an ErrorResponse object: an error wrapper with a stable code string, a human-readable message (Microsoft warns the message text may change over time; the code will not), and optionally innerHttpError. A 403 on a proactive send to a user who blocked the bot looks like this:

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
MS-CV: NXZpLk030UGsuHjPdwyhLw.5.0

{"errorCode":209,"message":"{\n  \"subCode\": \"MessageWritesBlocked\",\n  \"details\": \"Thread is blocked from message writes.\",\n  \"errorCode\": null,\n  \"errorSubCode\": null\n}"}

Every Connector response also carries an X-Correlating-OperationId header; capture it on failures - Microsoft support uses it to find the server-side log entry. In the C# SDK these failures throw ErrorResponseException (or HttpOperationException) with the response attached; in the JavaScript SDK the connector call rejects with an error whose statusCode carries the HTTP status.

All 24 codes

Jump to: Authentication & identity (5) · Permissions, policy & blocking (5) · Conversations & activities (5) · Rate limiting (1) · Payload & request errors (2) · Your endpoint & delivery (3) · Service errors (3)

Authentication & identity

CodeTitleHTTPType
401 BotNotRegisteredBotNotRegistered - no registration found
No registration found for this agent.
401Configuration
401 Unauthorized (invalid app ID / password)Invalid Microsoft App ID or password
AADSTS7000215: Invalid client secret provided.
401Configuration
401 Unauthorized (expired client secret)Expired client secret
AADSTS7000222: The provided client secret keys are expired.
401Configuration
401 Unauthorized (tenant mismatch)Single-tenant vs multi-tenant mismatch
AADSTS700016: The application wasn't found in the directory/tenant.
401Configuration
401 Unauthorized (token audience)Wrong token scope or audience
Authorization has been denied for this request.
401Configuration

Permissions, policy & blocking

CodeTitleHTTPType
403 BotDisabledByAdminBotDisabledByAdmin - blocked by tenant admin
The tenant admin disabled this agent
403Policy / account
403 ConversationBlockedByUserConversationBlockedByUser - user blocked the bot
User blocked the conversation with the agent.
403Policy / account
403 MessageWritesBlockedMessageWritesBlocked - proactive send to a blocking user
Thread is blocked from message writes.
403Policy / account
403 ForbiddenOperationExceptionForbiddenOperationException - app not installed in personal scope
Agent isn't installed in user's personal scope
403Configuration
403 NotEnoughPermissionsNotEnoughPermissions - operation requires rights the bot lacks
*scenario specific
403Policy / account

Conversations & activities

CodeTitleHTTPType
403 BotNotInConversationRosterBotNotInConversationRoster - bot removed from conversation
The agent isn't part of the conversation roster.
403Configuration
404 ConversationNotFoundConversationNotFound - conversation missing or deleted
Conversation not found.
404Permanent - do not retry
404 ActivityNotFoundInConversationActivityNotFoundInConversation - message missing or deleted
Conversation not found.
404Permanent - do not retry
405 Method Not Allowed405 - operation not supported by the channel
The channel doesn't support the requested operation.
405Permanent - do not retry
412 PreconditionFailedPreconditionFailed - concurrent operations on one conversation
Precondition failed, please try again.
412Retryable

Rate limiting

CodeTitleHTTPType
429 ThrottledThrottled - too many requests
Too many requests.
429Retryable

Payload & request errors

CodeTitleHTTPType
400 Bad ArgumentBad Argument - invalid request payload
*scenario specific
400Permanent - do not retry
413 MessageSizeTooBigMessageSizeTooBig - payload over the size cap
Message size too large.
413Permanent - do not retry

Your endpoint & delivery

CodeTitleHTTPType
403 InvalidBotApiHostInvalidBotApiHost - wrong cloud endpoint (GCC)
Invalid agent api host. For GCC tenants, call https://smba.infra.gcc.teams.microsoft.com.
403Configuration
502 Bad Gateway502 - bot returned an error / service dependency failure
Failed to send activity: bot returned an error
502Retryable
Unable to reach the app"Unable to reach the app" - invoke response timed out
Unable to reach the app
Configuration

Service errors

CodeTitleHTTPType
500 ServiceError500 - internal server error at the Connector
*various
500Permanent - do not retry
503 Service Unavailable503 - service temporarily unavailable
Service is unavailable.
503Retryable
504 Gateway Timeout504 - gateway timeout
Gateway Timeout.
504Retryable

Teams guides and tools

Other platforms

Frequently asked questions

Where do Microsoft Teams bot error codes actually appear?

In the HTTP response to your outbound Connector API calls (send, update, delete, create conversation). The body is an ErrorResponse object with a stable code string such as BotDisabledByAdmin or Throttled and a human-readable message. In the C# SDK these surface as ErrorResponseException or HttpOperationException; in Node the connector call rejects with an error carrying the statusCode. Inbound failures - your endpoint erroring - never appear here; they show up in your own logs and as 502s reported by the channel.

Why did my Teams bot suddenly stop responding after months of working?

The most common single cause is an expired Microsoft Entra client secret: secrets live at most 24 months, and expiry produces AADSTS7000222 in your logs while Teams shows users nothing at all. Check the app registration's Certificates & secrets blade first. Other silent stoppers are a rotated-but-not-deployed secret, an admin blocking the app (403 BotDisabledByAdmin), and an endpoint deployment that broke the messaging URL.

How do I know if a user blocked my Teams bot?

Teams fires no event when a user blocks or uninstalls a personal-scope app. The only signal is the error on your next send: 403 with code ConversationBlockedByUser on the reactive path, or 403 with subCode MessageWritesBlocked ("Thread is blocked from message writes.") on proactive sends. Microsoft explicitly documents compiling these per-user 403s into a blocked-users report. Treat the first such 403 as an unsubscribe and stop sending.

Which Teams bot errors are safe to retry?

Microsoft's retry guidance is explicit: retry 429 (using the Retry-After header), and retry 412, 502, 503, and 504 with exponential backoff plus jitter. Do not retry 400, 401, 403, 404, 405, 413, or 500 - the documented action for those is to fix the cause or stop sending. Retrying policy blocks like BotDisabledByAdmin just burns rate-limit budget without changing the outcome.

What rate limits produce 429 Throttled for Teams bots?

Three budgets: per bot per thread (for send-to-conversation: 7 operations/second, 8/2s, 60/30s, 1,800/hour), per thread across all bots (14 sends/second, 16/2s), and a global 50 requests per second per app per tenant. Roster and conversation reads have separate windows. Microsoft warns the exact values can change, so honor Retry-After and back off rather than hard-coding the numbers.

What does 502 "bot returned an error" mean in Web Chat or the Emulator?

It means your messaging endpoint failed - it threw, timed out, or returned 5xx - and the channel is reporting that as a 502 with body code BotRejectedActivity and message "Failed to send activity: bot returned an error". The fix is on your side: enable Application Insights, query exceptions, and implement the adapter's OnTurnError handler. A 502 on your own outbound send call is different: that one is a documented transient and should be retried.

Why does my Teams bot reply twice, or only sometimes?

Slow handlers. For invoke interactions (message extensions, dialogs) the documented budget is five seconds; Teams retries twice and ignores late responses, so a six-second handler executes three times and shows the user "Unable to reach the app". Regular activities are also redelivered when your endpoint answers slowly. Acknowledge fast, do heavy work asynchronously, and make side effects idempotent by activity ID.

What is the appId / password / tenant triangle?

Bot authentication needs three settings to agree: the Microsoft App ID (Entra application), the client secret issued for exactly that app, and the tenancy (MicrosoftAppType plus MicrosoftAppTenantId for single-tenant bots). Each mismatch has its own signature: AADSTS7000215 for a wrong secret, AADSTS700016 for a wrong app-or-tenant pairing, AADSTS7000222 for an expired secret. Verify the triangle with one cURL token request before touching any other layer.

How big can a Teams bot message be?

The documented bot message size limit is 100 KB, measured approximately over the whole activity - text, image links, mentions, reactions - encoded as UTF-16, excluding base64-encoded images. Microsoft recommends staying within 80 KB to guarantee delivery. Exceeding it returns HTTP 413 (RequestEntityTooLarge) with error code MessageSizeTooBig, which is not retryable: split the content or link out to it.

Do 201, 202, or 207 responses mean my Teams message failed?

No. The Connector API documents 200 and 201 as success and 202 as "the request was accepted for processing" - normal asynchronous delivery, with the ResourceResponse still carrying the activity ID you need for later updates or deletes. Treat any 2xx as success and store the returned id. Only 4xx and 5xx responses carry an ErrorResponse object and need handling.

Run your Teams bot without babysitting error codes

Conferbot manages the connection, tokens, webhooks and retries, and shows failures as readable status.