Back to field guides
Field report · production incident

Your DMARC says “aligned.” Proofpoint still marks you Spam. Here's why.

12 min read·Published 2026-04-18

Last month we shipped a transactional alert that Google delivered without incident and Proofpoint filed under Spam-Medium. Same sender. Same body. Same DMARC pass. Here is the full teardown, with the two things that fixed it.

The setup

We send two flavours of email from the same domain: transactional alerts (low volume, high urgency, single recipient) and weekly digests (higher volume, low urgency, list-style). Both pass SPF, DKIM, and DMARC with full alignment. Google treats them identically. Proofpoint treats them very differently.

Specifically: the digests get classified Negligible or Suspected Spam-Low, which is fine for a newsletter. The alerts get classified Spam-Medium, which is not fine, because the “your domain is being spoofed” email is quarantined at exactly the moment it matters.

What Proofpoint is actually scoring

DMARC pass gets you in the door. It does not get you a clean classification. Proofpoint's engine layers multiple classifiers after authentication, and the three that bit us are, roughly:

  1. Bulk-mail markers on a low-volume one-shot. If Precedence: bulk or List-ID or List-Unsubscribe appear on a message that classifier-2 flags as operational/urgent content, the two signals conflict. Classifier-1 says “this is newsletter plumbing.” Classifier-2 says “this reads like a one-off.” Mismatch gets penalised.
  2. Link: Author-Header / From-Header disagreement. If From: is "System Alerts" <alerts@acme.com>, Proofpoint expects the body to be system-alert-shaped. If you then drop in a rich HTML template with gradients, it penalises.
  3. Reply-To not matching a monitored mailbox. Proofpoint's heuristic considers an absent or unreadable Reply-To a spam signal. An absent one is documented; anoreply@ is tolerated; a Reply-To pointing to a domain that looks like yours but isn't getting PTR resolution is the worst outcome.

What we changed, exactly

Our transactional send path now classifies each template as tone=alert or tone=bulk. Alerts strip bulk markers; digests keep them:

# tone=alert  — transactional, operational, one-shot
# (no List-ID, no Precedence: bulk, no List-Unsubscribe)

# tone=bulk   — weekly digest, newsletter
Precedence: bulk
List-ID: Mailstinger digest <digest.alerts.acme.com>
List-Unsubscribe: <mailto:unsubscribe+digest@acme.com>
List-Unsubscribe-Post: List-Unsubscribe=One-Click

After that change: Proofpoint reclassified the alerts from Spam-Medium to Negligible on the next send. No DKIM change, no SPF change, no infrastructure move.

The second fix: the template

Our alert HTML used linear-gradient(…) CSS for the header band. It rendered beautifully in Gmail, Fastmail, and Outlook-for-Web. It rendered as a solid white block with no branding in the Outlook Word renderer that half of every enterprise inbox uses. That visual inconsistency is a classifier-2 input we didn't know about.

We replaced every linear-gradient with a flat solid colour on a <table> with bgcolorattributes. Same visual outcome everywhere, same classifier score in both rendering engines.

If you have a single lesson from this: modern mail filters score rendering inconsistency. Outlook has a weirder HTML engine than Gmail and that weirdness is not a rendering bug — it is a deliverability signal you didn't know you were emitting.

How to check if this is you

The fastest tell: open one of your transactional emails in the old desktop Outlook (not the new Outlook, not OWA — the Word- renderer one). If it looks dramatically different than in Gmail, you have the same bug.

The next tell: paste your headers into our header analyzer. If you see List-Unsubscribe on a message that isn't a newsletter, you're sending bulk markers on alerts.

What we built next

Mailstinger now ships with both classifications out of the box. Every template has a tone metadata field that maps to either alert or bulk at send time, and we assert on pre-send that the resulting SMTP envelope matches. We also normalise the HTML renderer contract — no gradients in any transactional template, and our brand palette exists as flat colour stops on table bgcolor attributes.

This is the kind of thing a SaaS platform should absorb so you never think about it again. If you'd rather not maintain your own deliverability rigging, that's our whole pitch.

Was this useful?

We publish one of these per incident. Want them in your inbox?