Blog
7 min read

SPF, DKIM, DMARC alignment: why your green checkmarks can still lie

SPF and DKIM can both pass while DMARC alignment quietly fails. How to read your Authentication-Results header and confirm the From domain actually aligns.

Warmbly team

Your mail can pass SPF, pass DKIM, and still fail DMARC. Authentication passing and alignment passing are two different checks, and the second one is where cold email quietly breaks while your vendor dashboard shows green.

This post walks through the mechanism, reads a real Authentication-Results header line by line, and gives you a 5-minute audit you can run today. If you want the full setup reference, the SPF, DKIM, and DMARC guide covers the DNS records themselves.

Authentication passing is not the same as alignment passing

DMARC does two things when a message arrives. It checks that SPF or DKIM passed, and then it checks that the passing one lines up with the domain in your visible From: address. That second step is alignment. You can clear the first and fail the second. When you do, DMARC fails even though both spf=pass and dkim=pass are sitting right there in the header.

That’s the trap. A sending service signs your mail with its own domain, the signature verifies cleanly, and DMARC still returns dmarc=fail because the domain that authenticated isn’t yours. Google’s bulk sender guidance requires SPF, DKIM, and DMARC with alignment for anyone sending bulk or marketing mail, so this isn’t a technicality you can skip.

SPF, DKIM, and DMARC in one sentence each

SPF is a DNS record listing which servers can send mail for your domain, checked against the envelope sender (the MAIL FROM, not the From: you see).

DKIM attaches a cryptographic signature to each message, tied to a domain in the signature’s d= tag, so the receiver can confirm the mail wasn’t forged or tampered with.

DMARC ties the two together. It tells receivers what to do when a message fails both, and it requires that at least one of SPF or DKIM aligns with the From: domain the recipient actually reads.

Why one of SPF or DKIM must align with your From domain

Alignment exists because the From: address is the only sender identity a human sees, and it’s trivial to forge on its own. SPF checks a hidden envelope address. DKIM checks whatever domain is in the signature. Neither is guaranteed to match the friendly From: unless DMARC forces the question.

So DMARC passes only if one of these holds:

  • SPF alignment: the MAIL FROM domain matches your From: domain
  • DKIM alignment: the DKIM d= domain matches your From: domain

You need one, not both. Most senders should run relaxed alignment, which matches on the organizational domain, so bounce.outreach.acme.com aligns with [email protected]. Strict alignment demands an exact match and only matters when you’re blocking a specific subdomain spoof. The common cold-email failure: a third-party sender authenticates everything under its own domain, so nothing aligns with yours, and DMARC fails despite two green passes.

Reading a real Authentication-Results header line by line

Open a message you sent to a Gmail or Outlook account, show the original or raw source, and find the Authentication-Results line. Here’s one that passes authentication but fails alignment:

Authentication-Results: mx.google.com;
  spf=pass (google.com: domain of [email protected]
    designates 198.51.100.7 as permitted sender)
    [email protected];
  dkim=pass [email protected] header.s=s1 header.b=Ab3xQ;
  dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=acme.com

Read it in order. spf=pass, good, but [email protected] is the vendor’s domain, not acme.com. Then dkim=pass, good, but [email protected] is again the vendor. The From: the recipient sees is header.from=acme.com. Neither authenticated domain matches it, so dmarc=fail.

The two tags that decide alignment are smtp.mailfrom (for SPF) and header.i or header.d (for DKIM). If neither matches your From: domain, you have work to do. A healthy result shows dkim=pass header.d=acme.com and dmarc=pass with header.from=acme.com.

The green-checkmark trap in vendor dashboards

Dashboards tend to render three rows: SPF pass, DKIM pass, DMARC pass. What they often mean is that the records exist and parse, not that they align with the From: domain on your live campaigns. A tool can honestly report DKIM pass while signing with header.d=mail.sendingtool.com, and unless it checks alignment against your sending domain specifically, the row stays green.

This is a common issue we see in support, and it maps onto the two details Google’s rules catch people on, which we walk through in what the bulk sender rules actually ask of cold emailers.

The SPF 10-lookup limit and other quiet failure modes

SPF has a hard cap: 10 DNS lookups per evaluation. Every include: in your record counts, and popular senders (Google Workspace, a CRM, a warmup or sending tool, a support desk) each add one or more. Stack enough and SPF returns PermError, which DMARC treats as a fail. The record still looks fine in a text editor, so this one hides well.

A few other ways both records read as present but the check breaks:

Failure modeWhat you seeWhy it fails
Over 10 SPF lookupsspf=permerrortoo many include: chains
Third-party DKIM onlydkim=pass, header.d is the vendor’ssignature doesn’t align with your From
SPF-only alignment with forwardingspf=fail after a forwardforwarding breaks the envelope path, and no DKIM to fall back on
DMARC p=nonedmarc=pass or fail but no enforcementpolicy is published but takes no action
Multiple SPF recordsspf=permerrormore than one v=spf1 record is invalid

The forwarding row is why relying on SPF alignment alone is fragile. When a message is forwarded, the envelope sender changes and SPF breaks, but a valid DKIM signature survives because it travels with the message body. Aligned DKIM is the more durable of the two. Get both, but if you only fix one, fix DKIM alignment.

A 5-minute alignment audit you can run today

Run this whenever you connect a new mailbox or change a sending tool:

  1. Send one campaign-style message from the mailbox to a Gmail address and one to an Outlook address.
  2. Open the message, view original or raw source, and find Authentication-Results.
  3. Confirm dmarc=pass. If it says fail, keep going.
  4. Check header.d= (DKIM) against your From: domain. If they match, DKIM aligns.
  5. Check smtp.mailfrom= (SPF) against your From: domain. If they match, SPF aligns.
  6. If neither aligns, add a DKIM key for your domain in the sending tool and republish so it signs with d=yourdomain.com.
  7. Count the include: entries in your SPF record. If you’re near 10, flatten or drop unused senders before you hit PermError.

Do this per domain, not per tool, since a domain aligned in one product can be unaligned in another. Alignment is the foundation, but it doesn’t move you from spam to inbox on its own. That comes from reputation and complaint rates, a separate problem from authentication. We pull that apart in why delivery rate isn’t inbox placement and across the broader deliverability guide.

Warmbly is open source under Apache 2.0, so if you want to see how the sending path handles authentication and signing, the code is at github.com/warmbly/warmbly. Fix alignment first. Everything downstream of the inbox assumes it.

Send cold email people actually open.

Connect a mailbox, warm it up, send your first campaign today.