JustEmails
PricingSign inStart free trialStart free
Tutorials··12 min read

DMARC Fails Even Though SPF Passes? How to Fix Alignment

SPF says pass, DMARC says fail, and every checker tool says the domain is fine. The culprit is almost always alignment — a Return-Path that belongs to your vendor instead of you.

By JustEmails Platform Team
Contents
  1. Why SPF Can Pass and DMARC Can Still Fail
  2. Alignment Modes: Relaxed vs Strict
  3. Step 1: Pull Raw Headers and Compare Two Domains
  4. Step 2: Read the Aggregate Report and Find the Failing Sender
  5. Step 3: Fix the Mismatch
  6. Step 4: Verify the Fix
  7. The Unpopular Opinion: Don't Go Strict
  8. Common Errors
  9. Frequently Asked Questions
  10. Why does DMARC fail when SPF passes?
  11. What is the difference between relaxed and strict DMARC alignment?
  12. How do I find the Return-Path of an email I received?
  13. Should I switch my DMARC record to strict alignment?
  14. Try JustEmails

You open a DMARC aggregate report and it makes no sense: DMARC failing even though SPF passes, row after row.

SPF: pass. DKIM: pass. DMARC: fail. Same message. Same report row.

Every checker comes back green. MXToolbox says the SPF record is valid. The vendor dashboard shows the domain as verified. And yet thousands of invoice notifications from your own domain sit in that XML marked fail, with receivers quietly quarantining a slice of them.

The natural reaction is to re-check the SPF record. Then re-check it again. Because when SPF says pass, your brain stops looking at SPF.

The record is usually fine. It just isn't being asked the question you think it's being asked. What broke is alignment — the part of DMARC nobody explains until it bites you.

We're the JustEmails team — JustEmails is built by Velocity Digital Labs. This is a common DMARC confusion, and it usually hits someone who already did everything right. Record published. Vendor verified. Still failing.

Why SPF Can Pass and DMARC Can Still Fail

Every email has two "from" addresses. Most people only ever see one.

The envelope sender (RFC5321.MailFrom, surfaced as the Return-Path header) is where bounces go — part of the SMTP conversation, not the visible message.

The header From (RFC5322.From) is the one in the mail client. billing@yourdomain.com. The one carrying your brand and, if spoofed, your reputation.

SPF only ever checks the first one. It takes the connecting IP, looks up the SPF record for the Return-Path domain, and answers yes or no. It has no opinion about the From address. None.

DMARC's job is to bolt those two identifiers together. It runs SPF, then asks a second question SPF never asks: did the domain SPF just validated match the domain in the From header? That question is alignment. If the answer is no, DMARC records fail.

The shape of the failure:

  • Your From address: billing@yourdomain.com
  • Your Return-Path: bounces+9f3a1@em4471.vendorhost.net
  • SPF result: pass (the vendor's IP is authorized for vendorhost.net)
  • SPF alignment: fail (vendorhost.net ≠ yourdomain.com)
  • DMARC: fail

And the part that trips up almost everyone: adding include:vendorhost.net to your SPF record does nothing here. Nothing at all. SPF is still evaluated against the Return-Path domain, which is still the vendor's. You authorized their IPs to send as your domain, but they're not sending as your domain at the envelope layer.

Alignment Modes: Relaxed vs Strict

Two tags control how forgiving alignment is. Most people never set them, which is fine — the defaults are the sane ones.

TagApplies toDefaultRelaxed (r) meansStrict (s) means
aspfSPF alignmentrOrganizational domains must matchExact hostnames must match
adkimDKIM alignmentrOrganizational domains must matchd= must equal From domain exactly

"Organizational domain" is the registrable domain, derived from the Public Suffix List. So under relaxed SPF alignment:

  • bounces.yourdomain.com vs yourdomain.com → aligned ✅
  • em4471.vendorhost.net vs yourdomain.com → not aligned ❌

Under strict, only an exact match survives — bounces.yourdomain.com fails against yourdomain.com. Which is why strict breaks so many working setups.

Check yours right now:

dig +short TXT _dmarc.yourdomain.com
# v=DMARC1; p=reject; adkim=r; aspf=r; rua=mailto:dmarc@yourdomain.com; pct=100

If aspf=s is in there and you don't remember putting it there, someone followed a hardening checklist a bit too enthusiastically. More on that below.

Step 1: Pull Raw Headers and Compare Two Domains

Before touching DNS, confirm the diagnosis on one message. Two minutes.

Get a failing message into Gmail. Open it, click the three dots, Show original. (Outlook: View → View message source.) You're looking for exactly three lines.

Return-Path: [bounces+9f3a1@em4471.vendorhost.net](mailto:bounces+9f3a1@em4471.vendorhost.net)
From: "Yourdomain Billing" [billing@yourdomain.com](mailto:billing@yourdomain.com)
Authentication-Results: mx.google.com;
       dkim=pass header.i=@vendorhost.net header.s=s1;
       spf=pass (google.com: domain of bounces+9f3a1@em4471.vendorhost.net designates 198.51.100.24 as permitted sender);
       dmarc=fail (p=REJECT sp=REJECT dis=QUARANTINE) header.from=yourdomain.com

Read it slowly. spf=pass, and right after it, dmarc=fail. The parenthetical even names the domain SPF validated — em4471.vendorhost.net, not yours. And header.i=@vendorhost.net means DKIM signed with the vendor's key, so DKIM alignment is failing too. Both mechanisms passed. Neither aligned. DMARC has nothing to fall back on.

That's the whole bug, in a few lines of text, invisible from every dashboard you'd normally check.

Step 2: Read the Aggregate Report and Find the Failing Sender

One message tells you a sender is broken. The aggregate report tells you which senders, how many messages, and since when. (No rua=mailto: in your record? Add it. Reports are free.)

They arrive daily as gzipped XML from Google, Microsoft, Yahoo, and anyone else enforcing DMARC. Unzip one, find the <record> blocks. Here's a failing one, trimmed:

<record>
  <row>
    <source_ip>198.51.100.24</source_ip>
    <count>4127</count>
    <policy_evaluated>
      <disposition>quarantine</disposition>
      <dkim>fail</dkim>
      <spf>fail</spf>
    </policy_evaluated>
  </row>
  <identifiers>
    <header_from>yourdomain.com</header_from>
  </identifiers>
  <auth_results>
    <spf>
      <domain>em4471.vendorhost.net</domain>
      <result>pass</result>
    </spf>
    <dkim>
      <domain>vendorhost.net</domain>
      <result>pass</result>
    </dkim>
  </auth_results>
</record>

Now compare the two SPF values. This is the tell, and almost nobody knows to look for it:

  • <auth_results><spf><result> → pass. The raw SPF verdict.
  • <policy_evaluated><spf> → fail. SPF after alignment.

Same record, two different answers. When those disagree, alignment is your problem — guaranteed. And <auth_results><spf><domain> hands you the offending Return-Path domain, which usually identifies the vendor on sight.

Two more fields worth reading:

  • <count> is volume. A source pushing 4,127 messages is production mail you must fix. A source pushing 3 is probably a forwarder — deprioritize it.
  • <policy_published> echoes back your aspf and adkim as the receiver understood them. Handy when you're unsure a DNS change propagated.

Parsing XML by hand gets old around report number six, and since each big reporter sends one file per domain per day, report number six lands on day two. dmarcian, Postmark's free DMARC Digests, and Valimail all ingest rua feeds and give you a source-by-source table. Use one, but still open the raw XML when something looks odd — summaries can hide the auth_results versus policy_evaluated split that explains the failure.

(Running several brands? Point every domain's rua at one parsing inbox, so there is one place to look.)

Step 3: Fix the Mismatch

Three real fixes, in order of preference.

Option A — set a custom Return-Path at the vendor. The right fix. Nearly every serious platform supports it; they just bury it under a different name each time.

  • SendGrid: Sender Authentication → Authenticate Your Domain. Automated Security gives you a CNAME like em4471.yourdomain.com → u12345678.wl.sendgrid.net. Once live, the envelope sender moves under your organizational domain and relaxed alignment passes.
  • Amazon SES: it's called "Custom MAIL FROM domain." Publish an MX for a subdomain (10 feedback-smtp.us-east-1.amazonses.com) plus a TXT record "v=spf1 include:amazonses.com ~all" on it.
  • Mailgun: use a sending subdomain such as mg.yourdomain.com with the DNS records Mailgun gives you on it.
  • Mailchimp and most marketing tools: look for "custom return path" or "custom bounce domain."

Same pattern everywhere: a subdomain of yours, DNS pointed at their infrastructure, bounce address under your registrable domain.

Four vendors, four names for one feature. When a vendor's docs turn up nothing for "Return-Path", search them for "bounce" instead.

Option B — fix DKIM alignment instead and let SPF fail. DMARC only needs one aligned mechanism. If a vendor won't give you a custom Return-Path but will sign DKIM with your domain, that's enough — spf=fail in policy_evaluated forever, dmarc=pass anyway. Ugly in reports. Works perfectly. If the vendor shows dkim=none instead, different problem: fixing DKIM for third-party senders.

DKIM alignment is the sturdier of the two anyway. It survives forwarding; SPF alignment doesn't.

Option C — move the sender to a delegated subdomain. Send from notifications@mail.yourdomain.com and hand that subdomain's authentication to the vendor wholesale. Apex reputation stays clean. Our dedicated sending subdomain guide walks the DNS.

What doesn't work: piling more include: statements into your SPF record. A fourth and fifth vendor include added to chase an alignment failure only inches you toward the ten-lookup ceiling — at which point SPF returns permerror and you've broken the mechanism that was working. Near that line? SPF flattening and the 10-lookup limit is the post you want.

Step 4: Verify the Fix

DNS first. Confirm the record exists before clicking any verify button:

dig +short CNAME em4471.yourdomain.com
dig +short TXT em4471.yourdomain.com

Then send a real message through the vendor — not a dashboard test, an actual production-path send, because some platforms use a different envelope for test mail. Show original, confirm Return-Path sits under your domain and dmarc=pass appears. (If those test sends go out through JustEmails, budget them against the account's daily sending ceiling, which counts mailbox and API sends together: for a newly verified domain, no more than 50 a day in the first week, 200 in the second, and up to 500 from day 15.)

Then wait. Aggregate reports lag 24 to 72 hours, so that 4,127-message source won't clear until the next window closes. Don't panic-revert on day one — it just adds a second variable.

The Unpopular Opinion: Don't Go Strict

Plenty of the harden-your-DMARC checklists out there tell you to set aspf=s; adkim=s. Skip it. I'll go further: if a checklist recommends strict without first asking what you send from and who sends on your behalf, stop reading that checklist.

Strict breaks subdomain senders, vendor bounce hosts, gateway-routed mail, and half your integrations — and buys almost nothing, because relaxed already requires an attacker to control a hostname under your registrable domain. If they've got that, you have a much larger problem than DMARC tags.

Strict fits a narrow case: an aggressive brand-protection program with every sender enumerated and monitored. If you landed here because invoices are going to spam, it's the opposite of what you need. Get to p=reject with relaxed alignment first — our DMARC ramp-up guide covers that path — and leave the tags alone.

Common Errors

spf=pass in headers, <policy_evaluated><spf>fail in reports. The one from the top of this post. Option A, or Option B if the vendor won't budge.

Everything was passing, then you added aspf=s and half your mail broke. Strict is now rejecting your own subdomain senders. Drop back to aspf=r and re-check in 48 hours.

A sender aligns on some messages, fails on others. Almost always two sending paths sharing one From address: your own mail server handling password resets, a vendor handling the marketing blast, each arriving from a different <source_ip>, each needing its own fix, and the daily report quietly averaging both into one row that looks like intermittent flakiness.

dmarc=fail on forwarded mail, everything else correct. A forwarder resends your message from its own server, so SPF alignment dies at the first hop. Expected. Not a misconfiguration. You can't fix other people's mailing lists, so don't burn a Saturday on it.

Vendor dashboard says "verified," reports still say fail. Verification usually means only that your SPF include and DKIM CNAME resolved. It does not mean a custom Return-Path is active. Two separate toggles at most vendors, and only one of them earns you a green check.

Trust the raw header. Not the dashboard.

Frequently Asked Questions

Why does DMARC fail when SPF passes?

Because SPF and DMARC check different domains. SPF validates the sending IP against the Return-Path domain (the envelope sender, also called RFC5321.MailFrom). DMARC then asks a second question SPF never asks: does that Return-Path domain match the From address your recipient actually sees? When a third-party tool sends for you, the Return-Path usually belongs to the vendor — something on sendgrid.net, mcsv.net, or amazonses.com — while the From address is yours. SPF passes for the vendor's domain, alignment fails for yours, and DMARC records a fail. Adding the vendor's include: to your SPF record does not fix this, because SPF is still evaluated against the vendor's domain, not yours.

What is the difference between relaxed and strict DMARC alignment?

Relaxed alignment (aspf=r, adkim=r — the default when you omit the tags) requires only that the organizational domains match. So a Return-Path of bounces.yourdomain.com aligns with a From address at yourdomain.com, because both resolve to the same registrable domain under the Public Suffix List. Strict alignment (aspf=s, adkim=s) requires an exact hostname match, so bounces.yourdomain.com would fail against yourdomain.com. Relaxed is the default for a reason: it already blocks the spoofing that matters, because an attacker still can't get a Return-Path under your organizational domain.

How do I find the Return-Path of an email I received?

Open the raw source. In Gmail, click the three-dot menu on the message and choose Show original. In Outlook, use View then View message source. Then look for the Return-Path header near the top — that domain is what SPF was actually checked against. Compare it to the From header. If they share a registrable domain, SPF alignment passes under relaxed mode. If the Return-Path is on a vendor host and the From is on yours, you've found the failure. The Authentication-Results header confirms it: you'll see spf=pass on one line and dmarc=fail on another.

Should I switch my DMARC record to strict alignment?

Almost certainly not. Strict alignment breaks a long list of legitimate setups — subdomain senders, vendors that use a per-customer bounce host, mail routed through a gateway — and buys very little extra protection, because relaxed mode already requires the attacker to control a hostname under your registrable domain. The teams that genuinely need aspf=s are the ones running an aggressive brand-protection program with every sender enumerated and monitored. If you're reading this post because your invoices are landing in spam, strict is the opposite of what you want. Fix the Return-Path first.


Try JustEmails

Unlimited custom domain email hosting for $49/year flat — unlimited domains, unlimited mailboxes, 10 GB storage, full IMAP/SMTP. Built for agencies, freelancers, and anyone managing email across more than one domain.

Start your 7-day free trial → · How it compares

dmarc-alignmentspf-pass-dmarc-failreturn-pathdmarc-aggregate-reportsemail-authenticationbuildinpublicsaasstudioaiworkforcebuildwithclaude

Related posts

Comparisons
OVH Email Alternative for European Hosting (Scaleway Included)
12 min read
Tutorials
Duplicate Emails Piling Up in Your IMAP Client? Here Is Why
13 min read
Tutorials
Mailbox.org Alternative: How to Migrate to JustEmails
11 min read