Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for Microsoft Teams By James Joyner IV · · 8 min read Last reviewed Jul 2026

Microsoft Teams Error: 'MessageSizeTooBig' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix the Bot Framework connector MessageSizeTooBig error (HTTP 413) when a Teams activity exceeds the ~28KB size limit: shrink text, cards, and attachments.

  • #microsoft-teams
  • #troubleshooting
  • #errors
  • #bot-framework
Free toolkit

Stuck on this Microsoft Teams error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

What this error means

The Bot Framework connector rejects an outgoing activity when the serialized payload exceeds the size Teams accepts for a single activity. When you POST to the conversation’s activities endpoint on the channel serviceUrl, the connector responds with HTTP 413 Payload Too Large and an error code of MessageSizeTooBig. This is the connector’s own size-enforcement path, not a client-side render failure.

The literal response body:

HTTP/1.1 413 Payload Too Large
Content-Type: application/json

{
  "error": {
    "code": "MessageSizeTooBig",
    "message": "Message size too big."
  }
}

The request that triggers it is a normal outbound activity send:

POST {serviceUrl}v3/conversations/{conversationId}/activities
Authorization: Bearer $BOT_TOKEN
Content-Type: application/json

Teams caps a single activity at roughly 28KB of serialized JSON. That budget covers everything in the activity: the message text, all Adaptive Card or rich card content, inline images encoded as base64, and metadata. This guide is about the connector returning MessageSizeTooBig for the whole activity; a card that renders but is individually oversized is covered separately in the Adaptive Card 28KB guide.

What users report

  • Outbound POST .../activities returns HTTP 413 with code: "MessageSizeTooBig".
  • Small test messages send fine, but messages with large cards or inline images fail.
  • Failures correlate with base64-embedded images rather than image URLs.
  • Long tables, logs, or generated reports pasted into card bodies trigger the error.
  • Activities that pass locally fail once real data (large descriptions, many rows) is populated.
  • Update/replace activity calls fail for the same payloads that failed on create.

Tenant and app configuration causes

  • Inline base64 images. Embedding image bytes directly in the activity or card inflates the JSON far past 28KB; a single medium photo easily blows the budget on its own.
  • Oversized Adaptive Card content. Deeply nested containers, long text blocks, or many Column/FactSet elements produce large serialized card JSON.
  • Unbounded dynamic data. Cards built from query results (log lines, tables, lists) with no row cap grow without limit as data volume grows.
  • Large attachments array. Sending many attachments, or several rich cards, in one activity sums past the limit even when each card is modest.
  • Verbose text fields. Dumping full stack traces, JSON blobs, or file contents into text fields consumes the shared byte budget.
  • Accidental duplication. Building the activity by concatenation or in a loop can duplicate attachments or text, doubling the payload unexpectedly.

Confirming tenant configuration

Measure the serialized size of the exact activity you send. The connector counts bytes of the JSON body, so serialize and measure that, not the object graph.

In C# (Bot Framework SDK):

var json = JsonConvert.SerializeObject(activity);
var bytes = System.Text.Encoding.UTF8.GetByteCount(json);
logger.LogInformation("Activity serialized size: {Bytes} bytes ({Kb} KB)", bytes, bytes / 1024.0);
if (bytes > 28 * 1024)
    logger.LogWarning("Activity exceeds Teams ~28KB single-activity limit");

In Node.js / JavaScript:

const json = JSON.stringify(activity);
const bytes = Buffer.byteLength(json, "utf8");
console.log(`Activity size: ${bytes} bytes (${(bytes / 1024).toFixed(1)} KB)`);

If you have a captured payload on disk, measure it directly and find the heaviest fields:

wc -c activity.json
jq '.attachments | length' activity.json
jq '[.attachments[].content | tostring | length] | max' activity.json

A large single attachment length or a huge content string points straight at the offending element. Grepping the payload for data:image quickly reveals base64 inlining:

grep -o 'data:image/[a-z]*;base64' activity.json | sort | uniq -c

Resolution

Bring the activity under the ~28KB budget. The fastest win is almost always to stop inlining images. Host images at a URL the Teams client can reach and reference them by url in the card image element instead of embedding base64 bytes:

{
  "type": "Image",
  "url": "https://cdn.example.com/reports/summary-2026-07.png"
}

For data-driven cards, cap the rows you render and link out for the rest. Show the top N items and provide an “Open full report” action rather than dumping every record into the card:

var top = rows.Take(20).ToList();
// render top 20 as FactSet/Table, add an Action.OpenUrl to the full report

When content is genuinely large, split it across multiple activities. Send a short summary activity, then follow with additional activities (or a paginated card with Action.Submit fetching the next page) so no single POST exceeds the limit. Move long text bodies out of the activity entirely by attaching a file or linking to a hosted document instead of pasting the content inline.

After trimming, re-measure with the diagnostic above before sending so you fail fast in your own code rather than at the connector.

Avoiding tenant drift

  • 28KB is the whole activity, not per element. Text plus every attachment shares one budget; a compact card can still push you over when combined with others.
  • UTF-8 byte count, not character count. Multibyte characters and escaped JSON make the byte size larger than the visible string length.
  • 413 is terminal for that payload. Retrying the identical activity will fail again; you must shrink it, not back off and resend.
  • Base64 is the usual culprit. Any data: URI in a card is a red flag; prefer hosted URLs the client can fetch.
  • Updates count too. Replacing an existing activity is subject to the same limit as creating one.
  • Watch aggregate attachments. Several individually-valid cards in one activity can still sum past the limit.
Free download · 368-page PDF

Fixed it? Get 500 Microsoft Teams & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.