Since February 2024, Gmail and Yahoo require DMARC for any sender pushing more than 5,000 messages per day to their users. Microsoft started enforcing similar rules a year later. If you're not publishing a DMARC record, your bulk mail is already being quarantined or rejected at the biggest inboxes in the world. The fix is short: one DNS record, a two-week observation period, and a careful tightening of policy.
Publish a TXT record at _dmarc.yourdomain.com starting with v=DMARC1; p=none; rua=mailto:reports@yourdomain.com. Read the reports for two weeks, fix any legitimate sender that's failing, then move to p=quarantine pct=25, ramp topct=100, finish at p=reject. The whole rollout takes 6 to 8 weeks in total.
How DMARC ties SPF and DKIM together
DMARC doesn't authenticate mail itself. It sits on top of SPF and DKIM and adds two things: a policy telling receivers what to do when authentication fails, and alignment — the requirement that the authenticated domain match the visible From header.
For a message to pass DMARC, at least one of the following must be true:
- SPF passes and the Return-Path domain aligns with the From domain, or
- DKIM passes and the
d=domain aligns with the From domain.
Alignment is why you can have spf=pass in your headers and still fail DMARC. That's covered in detail in our alignment failures guide — for now, the key insight is: DMARC is about the From domain the user sees, not the technical envelope.
Record syntax
A complete DMARC record looks like this:
v=DMARC1; p=quarantine; pct=25;
rua=mailto:dmarc-agg@brand.com;
ruf=mailto:dmarc-fail@brand.com;
aspf=r; adkim=r; sp=quarantine;
fo=1Tag by tag:
v=DMARC1— version, always DMARC1.p=— policy for the apex domain.none,quarantine, orreject.pct=— what percentage of failing mail the policy applies to. Used for gradual rollout.rua=— address for aggregate reports (daily XML summaries).ruf=— address for forensic (per-failure) reports. Rarely sent now due to privacy concerns.aspf=— SPF alignment mode.r(relaxed, default) ors(strict).adkim=— DKIM alignment mode, same options.sp=— policy for subdomains. Defaults to matchp=if omitted.fo=— failure reporting options.fo=1generates a report if any authentication mechanism fails.
The rollout plan
Never jump straight to p=reject. You will block your own transactional mail, your vendor's notifications, or a forgotten ESP — and the first you'll know is a customer complaining their password reset never arrived.
Follow the phases:
- Week 0 — Observe. Publish
p=nonewithrua=. Every message is delivered regardless of DMARC result; reports flow in. - Weeks 1–2 — Audit. Read aggregate reports. Identify every legitimate sender that's failing. Add SPF includes, enable DKIM, configure custom Return-Path where needed.
- Week 3 — Soft enforce. Move to
p=quarantine; pct=25. A quarter of failing mail now lands in Spam. - Week 5 — Full quarantine.
pct=100. All failing mail goes to Spam. Monitor reports for another week. - Week 7+ — Reject.
p=reject. Failing mail is rejected at SMTP, never delivered.
Setting up report reception
Raw DMARC aggregate reports are XML files delivered as daily emails from every major receiver. Reading them manually is miserable — each report is structured XML, and you'll get 10–30 per day from Gmail, Yahoo, Outlook, Mail.ru and every smaller ISP.
Use a parsing service. Free options with reasonable free tiers:
- Postmark DMARC Monitoring — free, clean UI, weekly digest emails.
- DMARCLY — free tier generous enough for solo senders.
- dmarcian — paid but industry standard; the free trial is enough for an initial audit.
- EasyDMARC — free-tier dashboards, decent report parsing.
Point your rua= at whichever service you pick. They give you a dedicated mailbox address to use in the tag.
Reading aggregate reports
Each report contains rows like:
source_ip: 209.85.220.41
count: 1247
disposition: none
spf: pass (aligned)
dkim: pass (aligned)
header_from: brand.comThat's Gmail sending 1,247 messages as you from your authorised Google Workspace infrastructure — everything passes and aligns. Good.
What you're looking for is rows like this:
source_ip: 52.14.88.201
count: 892
disposition: none
spf: pass (not aligned)
dkim: none
header_from: brand.comSPF passes (envelope was authenticated) but doesn't align with the From domain, and there's no DKIM signature at all. That IP is almost certainly an ESP you forgot to configure properly — likely sending From: you@brand.com with Return-Path bounces.esp.com. Fix DKIM alignment on the ESP, or configure a custom Return-Path so SPF aligns.
Once you're past the audit phase, reports become a monitoring tool. Look for new source IPs appearing — that's either a new legitimate vendor you forgot to authorise, or someone spoofing your domain.
Common mistakes
p=noneforever. The most common. You publishp=nonefor the compliance checkbox and never tighten. Gmail has started giving less weight top=nonerecords — it's nominally authenticated but practically useless for reputation.- No
rua=. Without reports you're flying blind. There's no point publishing DMARC if you can't see what's failing. - Hard jump to
p=reject. Breaks legitimate mail, takes days to diagnose, costs customers. - Strict alignment (
aspf=s) too early. This requires exact domain match. If you use any subdomain for bounces, you'll fail. Stay on relaxed until you've unified every sender. - Forgetting
sp=. If subdomain policy isn't specified, it inheritsp=. That might not be what you want — you may needsp=rejecteven while the mainp=isquarantine.
What DMARC doesn't do
DMARC is often oversold. It's important to know what it's not:
- It doesn't encrypt anything. TLS does that.
- It doesn't guarantee inbox placement. DMARC pass is necessary, not sufficient. Reputation, content and engagement still matter.
- It only protects the From header domain. Attackers can still use lookalike domains (
brand-secure.cominstead ofbrand.com) — DMARC can't help there. Use brand monitoring services for that. - It doesn't cover mail forwarded by indirect paths. Mailing lists that rewrite the From header break DMARC by design.
How to test
The fastest test: send a message that deliberately fails. Use a tool like dmarcly's DMARC test or our own placement test, which will route mail through unaligned senders and show you whether your policy kicks in. Look for disposition=quarantine or disposition=reject in the resulting aggregate report.
- Weeks 0–2:
v=DMARC1; p=none; rua=mailto:reports@yourdomain.com - Weeks 3–4:
v=DMARC1; p=quarantine; pct=25; rua=... - Week 5+:
v=DMARC1; p=quarantine; pct=100; rua=... - Week 7+ (once stable):
v=DMARC1; p=reject; rua=...