troubleshooting

Outlook Blocking or Stripping JSON and Code in Email? Complete Fix Guide

Key takeaways

  • why does outlook strip or block json from my email body? No single rule targets JSON specifically.
  • is it safe to put an api key or json payload in an email? Treat it as unsafe regardless of what any filter does.
  • why did my webhook notification email get marked as spam? Automated notification mail is the most common source of this problem because nobody reviews the body before it sends.

Short answer: Outlook and Microsoft's filtering do not have a single rule that says "block JSON." What actually happens is that raw code and structured data trip several unrelated systems at once - HTML rendering, content-pattern mail rules, credential detection, and malware heuristics - and any one of them can strip, rewrite, quarantine, or junk the message on its own. The fix is to stop sending code and JSON as literal message body text and use an attachment, a link, or properly escaped plain text instead.

  • If the message arrived but looks broken or cut off: the HTML renderer choked on unescaped angle brackets in your code - jump to the rendering section.
  • If the message never arrived at all, with no bounce: a content-matching mail rule, a credential-detection policy, or a malware heuristic most likely blocked or quarantined it.
  • If the message landed in Junk instead of the Inbox: the payload probably read as unfamiliar, automated content stacked on top of ordinary spam scoring.
  • If this is an automated notification, webhook, or error alert: skip to the section on automated senders - the fix belongs in the template, not in a one-off edit.

Why Code-Like Content Trips Filters

Email as a medium was built around formatted prose written for a human reader, and most of the systems that stand between a sender and an inbox were designed around that assumption. HTML rendering engines expect readable markup. Spam and phishing filters expect the shape of ordinary correspondence. Data-loss-prevention scanning looks for the shape of accidental disclosure. None of them were built with a single rule targeting "JSON" or "code," because no such rule needs to exist - a JSON payload or a code snippet already looks unusual to several of these systems at once, each for a different reason, and any one of them reacting is enough to change what happens to your message.

That is the part worth understanding before you touch anything: there is no single setting to find and switch off. A message can fail differently depending on exactly what it contains and who is receiving it, which is why the same webhook notification can arrive perfectly at one address, arrive mangled at a second, and never arrive at all at a third. The fix that actually works is structural - keep code and structured data out of the HTML-rendered body - rather than chasing whichever individual filter happened to react this time.

What Actually Happens: Four Outcomes

Before diagnosing anything, work out which of these four happened, because each points at a different system and a different fix.

OutcomeWhat causes itWhat you will notice
Rewritten or mangledAn HTML renderer misread unescaped angle brackets as the start of a tagThe message arrives shorter than you sent it, often cut off right after the first stray <
Silently strippedSpecific tags, attributes, or script-like patterns removed during renderingThe message arrives, but a section is missing with no visible sign anything was removed
Blocked or quarantinedA content-matching mail rule, a credential-detection policy, or a malware heuristicThe message never arrives; a bounce may or may not come back depending on how the block is configured
Filed to JunkGeneral spam scoring treats unfamiliar or automated-looking content as a negative signalThe message arrives, just not to the Inbox

The first two are rendering problems and have nothing to do with being blocked - the message got through, and something about how you built the HTML broke it on the way. The second two are filtering decisions, and they respond to a different set of fixes entirely. Confusing the two is the single most common reason people spend hours adjusting the wrong thing.

Why Filters Treat Code and JSON as Risky

Nothing about JSON or code is inherently malicious, but several independent, entirely normal parts of email security happen to key on features that structured content shares with genuinely dangerous mail.

It Resembles a Phishing Kit

Real phishing mail frequently carries obfuscated code, encoded payloads, redirect scripts, or fake-login markup embedded directly in the body. Security scanning is trained to recognize the structural shape of that pattern - dense brackets, encoded strings, key-value pairs that look like a form built to harvest input - regardless of whether the specific instance is actually harmful. A legitimate error payload or API response can share enough of that surface shape to get treated with the same suspicion, purely on structure.

It Can Trip Malware Heuristics

Anti-malware scanning looks for executable-like or obfuscated content: long encoded blobs, minified or compressed-looking text, embedded script tags, patterns that do not resemble natural language. Genuine JSON logs or source code can share those surface features - dense non-language text, repeated symbol sequences - even though the content itself does nothing when opened. The scanner cannot tell "harmless log dump" from "obfuscated payload" just by looking at the shape of the text; it reacts to the shape either way.

It Can Contain Credentials Without You Noticing

Organizations running Microsoft's compliance and security tooling can enable data-loss-prevention scanning that looks for the shape of credentials - API keys, access tokens, connection strings, private keys - inside a message body or attachment, and act automatically when a match is found by blocking, quarantining, or encrypting the message. A JSON error dump or webhook payload very often contains exactly that shape: a field named something like token, key, or secret sitting next to a long opaque string. You do not have to intend to send a live credential for that pattern to match - the scanner is matching shape, not intent.

It Does Not Read Like Something a Person Wrote

Beyond the three mechanical reasons above, general spam and bulk-mail scoring also weighs whether a message reads like ordinary human correspondence at all. A body that is mostly punctuation, field names, and opaque values has almost no natural-language content for a scorer to recognize as "a person wrote this to another person," which nudges the message toward the same bucket as templated marketing mail or outright automated spam - independent of whether anything about it is actually dangerous. This is a soft, cumulative signal rather than a hard block on its own, but it stacks with everything else on this page, and it is part of why a message that survives from an established sender can still get filed to Junk from a newer or less active one.

The HTML Rendering Problem

An email body sent as HTML gets parsed by a rendering engine the same way a web page does, and < and > are structural characters to that parser, not decoration. If code or JSON containing a comparison operator or a tag-like fragment gets pasted into the body without first converting those characters to their HTML entity form, the renderer reads it as the start of a tag it does not recognize - and the safest thing a renderer can do with an unrecognized tag is drop it, along with whatever came after it. That is why a message built this way often arrives shorter than it was sent, with everything past the first stray angle bracket missing.

Here is the same line of code shown two ways. Encoded properly, so a browser or mail client displays it as text:

if (retryCount < maxRetries) {
  attempt();
}

Paste that same snippet into an HTML-composed email body without converting the angle brackets first, and a rendering engine sees an unrecognized tag beginning at < maxRetries) { and reacts by dropping it - which is exactly the "arrived but cut off" symptom people report.

The same problem shows up inside JSON that never intended to contain any markup at all, whenever one of its values happens to include an angle bracket - a stored HTML fragment, a comparison string, or a value copied from another system that already had markup in it:

{
  "event": "shipment.status",
  "note": "carrier scan: weight < expected, flagged for recheck"
}

Every character in that block is safe to render because the bracket is properly encoded. Drop the encoding and paste the raw value instead, and the renderer treats weight < expected as the opening of an unrecognized tag named "expected," which does not exist, and the safe response is once again to discard it and whatever followed. JSON itself never requires angle brackets, which is exactly why this is easy to miss - it is not the JSON syntax causing the problem, it is whatever a field happens to contain.

This is not unique to Outlook. Every HTML email client - Gmail, Apple Mail, Outlook - shares this basic behavior, because HTML email inherited its rendering approach from the web. Desktop Outlook specifically has a well-known reputation for being the most restrictive of the major clients: for a long stretch of its history it rendered and composed HTML mail using Microsoft Word's own rendering engine rather than a browser-style one, which is why desktop Outlook has historically had weaker CSS support and a more aggressive habit of stripping markup it does not recognize compared to a modern browser. Outlook.com and the mobile Outlook apps use a different, more browser-like renderer, which is part of why the same message can look fine in one Outlook surface and broken in another.

ClientHow it tends to handle unescaped or unusual markup
Desktop OutlookMost restrictive of the major clients; historically renders through Word's engine, weak CSS support, aggressive about dropping markup it does not recognize
Outlook.com / mobile OutlookA separate, more browser-like renderer; generally more forgiving than desktop Outlook, but still applies its own spam and phishing scoring to the content
Gmail (web and app)Actively strips specific tags on render - script, form, iframe, and similar - rather than merely mishandling stray brackets
Apple MailCloser to a full browser engine; more tolerant of markup quirks, though still subject to Apple's own junk-mail filtering separately

The practical takeaway is not to pick a "safe" client to target, since every one of them still runs separate spam and security filtering on top of however it renders markup - it is to stop relying on any renderer's tolerance at all and keep the body itself clean, which is covered in the safe-sending section below.

Most modern compose windows - typing or pasting plain text directly into Gmail's or Outlook's own compose box - handle this conversion for you automatically. The danger is almost entirely in messages built programmatically, where a script or application constructs the HTML body itself and inserts raw text without running it through that same safe-encoding step first.

Content Rules That Match on Patterns

Organizations running Microsoft 365 can create mail flow rules that inspect the subject, body, and attachments of every message for specific words, phrases, or patterns and act on a match - reject it, redirect it, hold it for review, or attach a warning. A rule built to catch something else entirely, such as a pattern meant to flag account numbers or long numeric identifiers, does not know or care that the surrounding text happens to be a JSON payload. It matches the shape of the string it is looking for wherever that shape appears, including inside a field like "order_id": "8827441193" that has nothing to do with what the rule was built to catch.

Personal consumer inboxes on Outlook.com and Hotmail do not have an administrator configuring rules like this, but the platform runs equivalent automatic, pattern-based heuristics as part of its own spam and phishing detection, so a similar effect can show up there too without anyone deliberately configuring it. Either way, the practical lesson is the same: a rule or heuristic reacting to a pattern inside your JSON is not a judgment about your message specifically, it is a false-positive collision between two unrelated systems. For the wider set of content and link factors that affect Microsoft delivery generally, see our guide to Outlook and Microsoft 365 blocking your emails; this page is the deep dive on the code-and-JSON-specific case.

A concrete version of this: a rule built to catch sequences that look like payment card numbers - a common, entirely reasonable rule for a business handling customer data - matches on runs of digits in a specific length and grouping pattern. An order-confirmation webhook that includes a sixteen-digit internal order or shipment identifier in its JSON payload can trip that exact rule, get held for review or rejected, and nobody administering the rule ever intended to catch that traffic. From your side as the sender, this is invisible - there is nothing wrong with your authentication, your domain, or your reputation, and the rule was never about you specifically.

How This Interacts With Authentication and Reputation

Content-based checks are a separate gate from authentication - SPF, DKIM, and DMARC passing perfectly does not exempt a message from also being evaluated on what is actually inside it. A message can be authenticated flawlessly and still get stripped, blocked, or junked purely because of its body content, because these are independent systems answering different questions.

They do interact in one important way, though: content becomes the deciding factor mainly when a sender's reputation is already borderline. A well-established, properly authenticated sending domain with a clean history gets more benefit of the doubt on an unusual-looking message than a brand-new or unauthenticated one does - the same code snippet is far more likely to survive from a mailbox with a real sending history than from one with none. That means fixing the content is not a substitute for fixing authentication and reputation, and neither is a substitute for the other. Treat them as two separate checklists that both need to be clean.

This is also why the same automated notification template can behave inconsistently as it scales. A new integration sending its first handful of alert emails from a brand-new mailbox is operating with no history at all, so any borderline content gets weighed harshly. The exact same template, sent later from a mailbox with months of clean, engaged sending behind it, gets far more benefit of the doubt on the identical payload. If a notification template "used to work fine" and recently started getting filtered, check whether the sending mailbox or domain itself changed - a new integration, a new subdomain, a mailbox that went quiet and lost engagement - before assuming the template's content is suddenly the problem.

Safe Ways to Send Structured or Code Content

The reliable fix is to stop putting code and JSON directly into the HTML-rendered body at all. Three approaches work, in order of preference.

Attach It Instead of Inlining It

A .json, .txt, or .log file attached to a short, human-written message keeps the risky content out of the part of the email that gets rendered as markup and matched against content rules. Attachments do go through their own scanning - that is normal for any attachment and not specific to code - but that scanning is checking for genuinely malicious files, not penalizing the mere presence of structured text the way inline body content can be.

Link to It Instead of Pasting It

Hosting the payload, log, or output somewhere your recipient can reach - a dashboard, a documentation page, an issue tracker, an internal tool you already use - and linking to it keeps the email itself short and readable while making the full content available on demand. The linked domain carries some reputation weight of its own, so link to an established, recognizable destination rather than a redirect chain or an unfamiliar shortener, which is treated as suspicious in its own right.

If You Must Show It Inline, Escape and Fence It Properly

Convert every literal <, >, and & to its HTML entity form before it goes into the body, and keep the result inside a clearly bounded, monospaced block rather than dropping raw text into a paragraph. Keep it short - the relevant few lines, not a full log dump. Most mail clients handle this conversion automatically when a human types or pastes into the compose window; the failure case is almost always a script or application building the HTML body directly and skipping that step.

Never Put Real Secrets in an Email Body

Independent of anything a filter does, this is a security rule worth following on its own: live API keys, passwords, access tokens, private keys, and connection strings should never travel by email, encoded or not. Email is not an access-controlled, encrypted-at-rest channel - it sits in inboxes, forwarding chains, and search indexes indefinitely, often on more devices than the sender realizes. If a filter catches a message like this and blocks it, that is arguably the system working as intended.

If a real credential ever does go out this way, rotate or revoke it immediately regardless of whether the message was delivered or blocked. A block does not guarantee nobody saw the content - some content-matching rules hold a message for an administrator to review rather than deleting it outright, which means a person may have already read exactly the secret you were trying to keep contained.

This applies to internal notification mail just as much as anything sent to a customer. An engineering team emailing itself an alert containing a live database connection string or a third-party API key is a routine, everyday habit that feels harmless because the audience is "just us" - but the message still leaves the original system, still gets copied by every forward and every mailbox rule downstream, and still sits in a search index long after the incident that generated it is forgotten. Build the habit of masking or omitting credential-shaped fields in every outbound template, not only the ones that leave the company.

Webhook, Error Alert, and CI/CD Emails

This problem shows up most often not from a person deliberately pasting code, but from an automated system generating an email as a side effect - a webhook handler emailing itself a payload on failure, a monitoring tool emailing a stack trace, a build pipeline emailing a log tail. These are exactly the senders least likely to have a human review the body before it goes out, which means the fix needs to live in the template once, rather than being remembered on every individual send.

Render the notification as a short, plain sentence with the essential facts and a link to the full detail in your own system - something like "Payment webhook failed for order 4821 - view the full payload" rather than dumping the raw response into the message body. If a short excerpt genuinely speeds up triage, cap its length, escape it properly, and keep it inside a clearly fenced block rather than letting it run freely through the rest of the message. Automated notification streams like this are also fighting a second, separate deliverability battle - the one covered in our guide to transactional and automated emails getting blocked - so if this kind of mail is also arriving unreliably in general, work through that guide alongside this one rather than assuming content is the only cause.

Testing a New Notification Template

Before turning on a new automated template that will fire hundreds or thousands of times, test it the same way you would test any other new sending pattern - not by reading the code, but by watching what actually happens on delivery.

  1. Send it to accounts you control at the major providers first. A Gmail address, an Outlook.com or Microsoft 365 address, and one more if you have it. Check every folder, not just the Inbox, since a message filed to Junk or a Promotions-style tab is a completely different outcome from one that never arrived at all.
  2. Trigger the real failure path, not just the happy path. If the template exists to report an error, actually trigger that error in a test environment so the payload it emails is the real shape and size your system produces under failure - a hand-written test payload is often shorter and cleaner than what a real crash or a real API error actually returns.
  3. Check what arrives against what you sent. Open the raw source of the delivered message where your mail client allows it, and confirm nothing is missing compared to what you triggered. A shorter-than-expected body is the rendering problem described earlier, not a sign the send failed.
  4. Scan the payload itself for anything credential-shaped before it ever reaches a template - field names like token, key, secret, password, or authorization, sitting next to a long opaque value - and strip or mask those fields in the template output regardless of whether a filter would catch them.
  5. Re-test after any change to the payload shape, not just after a change to the email template. The two are more tightly coupled than they look, since the payload's shape is what a content filter is actually reacting to.

Quick Diagnostic Checklist

  1. Did the message arrive but look cut off or broken? Check for unescaped < or > characters in the body - that is a rendering problem, not a block, and the fix is escaping, not deliverability tuning.
  2. Did the message never arrive, with no bounce? Check whether the content contains anything shaped like a credential - a field named key, token, secret, or password next to an opaque string is exactly the pattern credential-detection scanning looks for.
  3. Did it arrive but land in Junk? Check authentication and sending reputation first - content alone is rarely the sole cause when the underlying sending identity is otherwise strong.
  4. Is this an automated or notification sender? Fix the template structurally - move the payload to a link or attachment - rather than editing individual messages after the fact.
  5. Still stuck? Work through the general framework in our emails-not-being-delivered diagnostic guide to pin down exactly which of the four outcomes above you are actually looking at.

Preventing This With WarmySender

To be direct about what this does not solve: WarmySender does not scan, rewrite, or approve your message content, and it cannot override a recipient's content-matching mail rule or a credential-detection policy running on their own systems. What is inside the body, and what the recipient's own filtering is configured to do with it, is entirely outside anything a sending platform can control.

What WarmySender does is strengthen the other half of the equation described above: gradual warmup ramp on every new mailbox, per-mailbox daily sending caps, paced sending instead of bursts, mailbox health monitoring, and list verification before a send, running across cold email campaigns, LinkedIn and Instagram outreach, and multichannel sequences that combine them. Since content only becomes the deciding factor once reputation is already borderline, a well-warmed, properly authenticated mailbox has far more room for an occasional legitimate code snippet or JSON excerpt than a cold or shaky one does. For the specific case of automated notification and webhook mail, that traffic usually runs through a completely separate sending pipeline from outreach - see the transactional guide linked above for that side of the picture. Setup guidance lives in the documentation. Start at warmysender.com.

Frequently asked questions

why does outlook strip or block json from my email body?
No single rule targets JSON specifically. Raw structured content trips several independent systems at once: the HTML renderer can misread unescaped angle brackets as broken markup, content-matching mail rules can false-positive on a pattern inside the payload, and credential-detection scanning can flag a field that looks like an API key or token. Any one of those reacting is enough to strip, rewrite, or block the message, which is why the same payload behaves differently across recipients.
is it safe to put an api key or json payload in an email?
Treat it as unsafe regardless of what any filter does. Email is not an access-controlled, encrypted-at-rest channel - messages sit in inboxes, forwarding chains, and search indexes indefinitely. A JSON payload containing a field like token, key, or secret next to an opaque string is exactly the shape credential-detection scanning looks for, and getting blocked is often the system doing you a favor. If a real credential ever goes out this way, rotate it immediately, whether the message was delivered or not.
why did my webhook notification email get marked as spam?
Automated notification mail is the most common source of this problem because nobody reviews the body before it sends. A raw payload dumped into the message looks structurally similar to phishing infrastructure and malware heuristics, both of which key on dense, encoded, unnatural-looking text regardless of actual intent. The durable fix is template-level: render a short plain sentence describing what happened with a link to the full payload in your own system, rather than embedding the raw response in the email body.
does attaching a file avoid outlook's content filtering?
It avoids the specific problems tied to HTML rendering and body content-matching, because the risky content is no longer sitting inside the part of the message that gets parsed as markup and scanned for patterns. Attachments go through their own malware scanning, which is normal for any attachment and not specific to code, but that scanning checks for genuinely malicious files rather than penalizing the presence of structured text the way inline body content does.
why does my html email look broken or cut off when I paste in code?
Angle brackets are structural characters to an HTML renderer, not plain text. If code containing a comparison operator or a tag-like fragment is pasted into an HTML email body without converting it to its HTML entity form first, the renderer reads it as the start of an unrecognized tag and drops everything from that point onward. This is a rendering problem, not a deliverability block - the message was delivered, it just arrived shorter than you sent it.
will using pre and code tags stop outlook from blocking my email?
Formatting tags alone do not prevent a block, because content-matching rules and credential scanning look at the actual text inside those tags, not the tag names wrapped around it. What matters is whether the angle brackets and special characters inside the block are properly escaped, and whether the content itself still contains something that reads as a credential or an unfamiliar pattern. A pre or code block helps with readability and keeps rendering intact, but it is not a filtering bypass.
does this happen on gmail too, or just outlook?
Yes, though the specifics differ. Gmail's renderer strips certain tags outright and applies its own spam scoring to unfamiliar or automated-looking content, and any provider with data-loss-prevention or content-pattern scanning enabled on the receiving end can flag the same credential-shaped strings. The underlying causes - broken HTML from unescaped brackets, content that looks like a credential, payloads that resemble phishing or malware infrastructure - are not specific to Microsoft, even though Outlook's rendering history makes it the client people notice the rendering half of this problem on most.
can json in an email body get flagged even with clean spf, dkim, and dmarc?
Yes. Authentication and content filtering are separate, independent checks answering different questions - passing one says nothing about the other. A perfectly authenticated message can still be stripped, blocked, or junked purely because of what is inside the body. Strong authentication and sending reputation do make content-based checks less likely to be the deciding factor, since providers extend more benefit of the doubt to established senders, but they do not exempt a message from being scanned in the first place.
AK
Technical Content Lead · WarmySender
Writes about email deliverability, sender reputation, cold outreach, and LinkedIn prospecting — turning the mechanics of the inbox into plain-English playbooks.