Back to blog
Threat Intel
Phishing Forensics

Anatomy of a BIMI Outage: How One Bad Character Broke Our SVG

Our DMARC was perfect, our DNS was solid, yet our logo vanished from millions of inboxes for 72 hours because of a single misplaced ampersand.

MailSleuth Research
Email Security Team
June 30, 20268 min read
An illustration of a glowing wireframe logo flickering out of existence because of a single, broken ampersand character

It started on a Tuesday. A Slack message from Marketing: 'Hey, is something wrong with the logo in Gmail?' It was gone. Where our brand's logo should have been sitting confidently next to the subject line in millions of inboxes, there was just a generic, gray initial. My stomach dropped. This wasn't just a cosmetic bug; it was a brand trust issue, and it was happening at scale.

The initial triage felt like a cruel joke. Every light was green. Our DMARC policy, published in DNS as per RFC 7489, was at a full `p=reject`. SPF (RFC 7208) and DKIM (RFC 6376) were passing and aligned. Authentication-Results headers confirmed it. We hadn't touched the DNS records in months. From the perspective of the email authentication stack, we were perfect.

So began a 72-hour ghost hunt. The problem wasn't in the authentication protocols we spend our lives defending. It was hiding in plain sight, inside the very file we were trying to promote, waiting for a single parser to be slightly less forgiving than a web browser.

The Clean Bill of Health That Lied

When you see a BIMI failure, your muscle memory kicks in. You check the core requirements. First, DMARC. I ran a quick `dig txt _dmarc.ourdomain.com` and confirmed our policy was `v=DMARC1; p=reject; rua=mailto:dmarc@ourdomain.com;`. No `pct<100`, no `sp=none`. It was as strict as it gets. This is the non-negotiable foundation for BIMI; without it, mailbox providers won't even attempt to fetch your logo.

Next, the BIMI record itself. It lives at `default._bimi.ourdomain.com`, and ours was simple: `v=BIMI1; l=https://cdn.oursite.com/brand/logo.svg;`. The URL was correct. I could paste it into my browser and the logo loaded instantly. The server returned a 200 OK. We even had a valid Verified Mark Certificate (VMC), though that's not strictly required by all providers. Everything looked textbook.

Authentication-Results: mta.google.com; dkim=pass header.i=@ourdomain.com header.s=selector1 header.b=xyz; spf=pass (google.com: domain of sender@ourdomain.com designates 203.0.113.10 as permitted sender) smtp.mailfrom=sender@ourdomain.com; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=ourdomain.com

The final sanity check was a raw email header from a test send. The `Authentication-Results` header, the official scorecard written by the receiving mail server, was pristine. SPF `pass`. DKIM `pass`. DMARC `pass`. This is the point where most triage checklists end. The data from the receiving MTA was telling us a clear story: authentication is solid, the policy is correct, and we are eligible for BIMI. Yet, no logo appeared. The evidence and the outcome were in direct contradiction.

Chasing Ghosts in the Network Stack

If the DNS and email authentication layers are solid, the next suspect is the delivery of the asset itself. The BIMI spec requires the logo to be served over HTTPS. Any certificate errors, mixed content warnings, or redirects could cause a fetch failure. But our CDN was configured correctly with a valid TLS certificate.

Auditing HTTP Headers

The headers served with the SVG are just as important as the file. I used `curl -I https://cdn.oursite.com/brand/logo.svg` to inspect the response. The primary requirement here is the `Content-Type`. It must be `image/svg+xml`. Ours was. A common misconfiguration is serving it as `image/svg`, `text/plain`, or even `application/octet-stream`. Mailbox providers are strict; the wrong content type is an immediate failure. Again, we passed inspection. Status code was 200 OK. No strange `Cache-Control` headers, no unexpected redirects. Nothing.

Considering CORS and Server Policy

While BIMI fetching is a server-to-server request and not subject to the same browser-based CORS (Cross-Origin Resource Sharing) policies that plague web developers, it's still worth checking for any overly restrictive server configurations. Were there IP-based allow-lists? Aggressive WAF rules that might be blocking the user-agent of Google's or Verizon's fetcher bots? We scoured the CDN logs for blocked requests that matched the timestamps of our test emails. We found nothing. Every request for the SVG file was met with a 200 OK and the file was delivered. The ghost was still in the machine.

The Smoking Gun in the SVG Itself

We had eliminated DNS, DMARC, HTTPS, and HTTP headers. What was left? The one thing everyone assumed was fine because it rendered perfectly in Chrome: the SVG file itself.

I downloaded the file and opened it not in an image viewer, but in a plain text editor. This is a critical lesson: browsers are incredibly forgiving of broken code. They are designed to make a best-effort attempt to render whatever garbage they receive. A security-conscious, automated parser used by a major email provider is the polar opposite. It is designed to be pedantic and fail on any ambiguity.

<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <!-- ... some valid paths ... --> <image href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAA...[snip]...B2QJI&p=xyz...."/></svg>

And there it was. Buried deep inside a `data:` URI for an embedded raster image, was a single, unescaped ampersand (`&`). The marketing team had recently used a new design tool to add a tiny bitmap element to the vector logo. The tool's SVG export, while visually correct, produced non-compliant XML. The `&` character is reserved in XML to begin an entity reference, like `&amp;` for an ampersand or `&lt;` for a less-than sign. The BIMI group's parsers saw this naked `&` and correctly interpreted the file as malformed XML, discarding it immediately. No logo. No error message returned to us. Just silence.

Root Cause: XML Syntax vs. Data Blobs

To truly understand the failure, you have to remember that an SVG file isn't just an image—it's a text document structured as XML. The rules of XML are rigid and unforgiving, and they apply to everything within the file, including attribute values.

The Data URI Deception

Embedding a Base64-encoded PNG or JPEG inside an SVG is a common practice, but it's a minefield. The `href` attribute of the `<image>` tag contains the entire Base64 string. The problem is that the Base64 character set (`A-Z`, `a-z`, `0-9`, `+`, `/`) is perfectly capable of producing character sequences that have special meaning in XML. Our file contained an `&`.

The SVG parser doesn't know it's looking at a Base64 blob. It's just scanning a string attribute. When it encounters the `&`, it expects a valid entity name to follow, like `amp;`. When it sees `&p=`, it throws up its hands and declares the document invalid. The fix was painfully simple: find and replace `&` with `&amp;` inside the data URI. After doing that and re-uploading the file, our logo reappeared in inboxes within the hour.

The SVG P/S Profile

This incident highlights the importance of the specific SVG profile required by BIMI: SVG Tiny Portable/Secure (SVG P/S), which is a stricter subset of the already-strict SVG Tiny 1.2 standard. This profile explicitly forbids external resources, scripts, and other interactive elements that could pose a security risk. While our `&` issue was a basic XML syntax violation, many SVG export tools produce files with extraneous metadata, `<script>` tags, or other features that also violate SVG P/S and will cause BIMI to fail silently. You must validate against this specific profile, not just against whether it 'looks right'.

Building a Resilient Asset Pipeline

A 72-hour outage caused by a single character is a humbling experience. It's a clear signal that our process for managing brand assets intended for security-sensitive contexts was flawed. Hope is not a strategy; we needed a programmatic solution.

Automated Linting is Non-Negotiable

The root cause was a faulty export from a design tool. We can't control third-party software, but we can control what we accept into our production environment. The fix is to integrate automated SVG validation into the asset pipeline. Before any new logo file is pushed to the CDN, it must pass a strict linter.

This can't be a generic XML validator. It needs to check for SVG P/S compliance specifically. It must check for illegal attributes, forbidden elements like `<script>`, and, as we learned, ensure proper entity escaping within attribute values. This check should be a blocking step in the CI/CD pipeline for the marketing team's asset repository. If the linting fails, the commit is rejected, and the file never gets near the CDN.

This moves the point of failure from a public-facing outage to a developer's local machine, which is exactly where it belongs. It provides immediate feedback and prevents the entire class of problem from recurring.

The takeaway

BIMI's apparent fragility is a feature, not a bug. For years, web browsers have trained us to be sloppy, accepting malformed code and rendering it anyway. BIMI, by contrast, operates in the unforgiving world of security protocols where strict validation is paramount. There is no 'best effort'—there is only valid or invalid. Your brand's logo now depends on your organization's XML hygiene.

The incident forced us to treat a marketing asset with the same rigor as a piece of application code. Continuous monitoring of the entire chain—from the DMARC record in DNS to the `Content-Type` header on your CDN to the byte-level validity of the SVG file itself—is the only path to reliable brand presence in the inbox. Automated tooling that can watch this entire stack, whether it's a combination of open-source scripts or a platform like MailSleuth.AI, is no longer optional infrastructure.

#bimi#dmarc#email-security#svg#debug-bimi-svg-file#postmortem
MailSleuth Research
Email Security Team

We dissect phishing campaigns and email infrastructure so you don't have to.