Subdomains, sp= and the domains you forgot
A DMARC record on the parent domain covers every subdomain by default. That is usually what you want, and occasionally exactly what breaks things.
When a receiver looks for DMARC policy, it checks _dmarc on the From domain. If there is no record there, it falls back to the organisational domain's record and applies that record's sp= value, or, if sp= is absent, its p= value.
What this means in practice
- Publishing p=reject on example.com enforces reject on marketing.example.com, staging.example.com and every other subdomain, published or not.
- A subdomain with its own _dmarc record uses that record and ignores the parent entirely.
- sp= on the parent only applies to subdomains without their own record.
The staged rollout pattern
During a rollout you can hold the parent at a strict policy while giving a lagging subdomain more time:
_dmarc.example.com TXT v=DMARC1; p=reject; sp=quarantine; rua=mailto:dmarc@example.com
_dmarc.legacy.example.com TXT v=DMARC1; p=none; rua=mailto:dmarc@example.comTreat a per-subdomain p=none as temporary and put a date on it. A permanent exemption is a permanent hole, and attackers enumerate subdomains.
Non-sending subdomains
Subdomains used for web, API or internal services never send mail, so lock them down explicitly where you can: SPF of v=spf1 -all, and a null MX record of 0 . to state that the name accepts no mail either.
app.example.com TXT v=spf1 -all
app.example.com MX 0 .More on DMARC
What DMARC actually does
DMARC binds SPF and DKIM to the From address your recipients see, tells receivers what to do on failure, and sends you reports about it.
Every DMARC tag, and which ones matter
A DMARC record has eleven possible tags. Four of them do the work; the rest are tuning you will rarely touch.
Publishing your first DMARC record
Start at p=none with a reporting address. It changes nothing about delivery and gives you the data you need for every decision that follows.