SPF and DKIM both have a quiet failure mode: they can each return pass without protecting your domain. SPF passes against the SMTP envelope, which receivers don't display. DKIM passes against whichever domain signed the message, which is often the ESP's domain, not yours. DMARC is the policy layer that closes that gap by requiring alignment with the domain users actually see — and by giving you reports so you can find out who is sending under your name.
What DMARC actually does
DMARC (RFC 7489) is a DNS TXT record at _dmarc.yourdomain.com that does three things. It declares an alignment requirement on top of SPF and DKIM. It publishes a policy — none, quarantine, or reject — that tells receivers what to do with mail that fails. And it gives receivers an address to send aggregate reports to, so you can see authentication results across the entire receiving ecosystem.
A minimal record looks like this:
_dmarc.yourdomain.com TXT "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; fo=1"DMARC alignment, precisely
Alignment is the single concept that decides whether DMARC passes. The visible From: header has a domain. DMARC checks that at least one of SPF or DKIM passed and the domain it authenticated matches that From domain.
- SPF alignment compares the domain in
MAIL FROM(the SMTP envelope sender) to the From header domain. - DKIM alignment compares the
d=tag in the DKIM signature to the From header domain.
Alignment can be strict (exact match) or relaxed (organisational-domain match — mail.yourdomain.com aligns with yourdomain.com). The record tags are aspf=r|s and adkim=r|s. Relaxed is the default and almost always what you want; strict alignment breaks subdomain senders.
The flow at a receiver:
From: alice@yourdomain.com
SPF check → pass (envelope: bounces@yourdomain.com) → aligned
DKIM check → pass (d=yourdomain.com) → aligned
→ DMARC pass
vs.
From: alice@yourdomain.com
SPF check → pass (envelope: bounces@esp.example) → NOT aligned
DKIM check → pass (d=esp.example) → NOT aligned
→ DMARC fail, apply p= policyp=none, p=quarantine, p=reject
The policy tag is the lever that turns DMARC from telemetry into enforcement.
p=none
Observation only. Receivers take no action on failing mail, but they do send aggregate reports if you specified rua=. This is the right starting point because it lets you discover every legitimate sender before you start blocking anything. It is not a destination — staying at p=none means your domain remains spoofable.
p=quarantine
Receivers send failing mail to the spam folder. This is your enforcement ramp. Combined with pct=, you can apply quarantine to a percentage of failing mail and observe the impact in your reports before tightening further.
p=reject
Receivers reject failing mail at SMTP time — it never reaches the recipient, and the sender gets a bounce. This is the only policy that actually stops spoofing of your domain. Major receivers (Gmail, Yahoo) increasingly require it for high-volume senders.
How to ramp from p=none to p=reject without breaking things
The mistake is jumping straight to enforcement. The right sequence:
- Inventory. Publish
p=nonewithrua=pointed at a parser (commercial or self-hosted). Collect two weeks of reports. - Fix the obvious. For every legitimate sender, ensure SPF includes them (see the SPF lesson) and that DKIM is signed with your domain in
d=(see the DKIM lesson). - Quarantine at 25%. Move to
p=quarantine; pct=25. Watch reports for a week. - Quarantine at 100%. Drop the
pct=tag. Watch for another week. - Reject. Switch to
p=reject. Leave reporting on permanently.
Reading aggregate (rua) reports
Aggregate reports are XML files sent daily by participating receivers. Each report contains rows summarising authentication results grouped by source IP. The fields you actually use:
<record>
<row>
<source_ip>198.51.100.42</source_ip>
<count>318</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>fail</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>yourdomain.com</header_from>
</identifiers>
<auth_results>
<dkim><domain>yourdomain.com</domain><result>pass</result></dkim>
<spf><domain>esp.example</domain><result>pass</result></spf>
</auth_results>
</record>The pattern above is the classic ESP-misalignment case: SPF passes against the ESP's envelope domain but doesn't align, DKIM passes and aligns, so DMARC passes overall. The row to worry about is one where both dkim and spf under policy_evaluated are fail — that is either misconfigured legitimate mail or spoofing.
How to check your DMARC record
The DMARC checker resolves and parses your record, flags syntax errors, and surfaces common misconfigurations like missing rua= or unreasonable pct= values. Pair it with the SPF checker and DKIM checker to verify the underlying mechanisms DMARC depends on.
When you're ready to deploy
The per-ESP DMARC setup pages show the literal records to publish:
- DMARC for Google Workspace
- DMARC for Microsoft 365
- DMARC for SendGrid
- DMARC for Mailgun
- DMARC for Amazon SES
Once you are at p=quarantine or p=reject, you unlock the next layer of inbox identity: BIMI, which puts your verified logo in the inbox and requires enforced DMARC as a prerequisite.
Looking for the short definition? See DMARC in the glossary.
