All tips
DMARC 1 min read

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.com

Treat 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 .
Check your DMARC policy
dmarcsubdomainspolicy