DMARC for subdomains: the sp= tag, and the subdomains you forgot about
You published DMARC on your domain — but what happens to mail claiming to be from invoices.yourdomain.com, a subdomain that doesn't even exist? The answer is the sp= tag, and it's worth two minutes of your time.
How subdomains inherit your policy
When a receiver checks DMARC for mail whose From address is billing.example.com, it looks for a record at _dmarc.billing.example.com first. Almost no one publishes per-subdomain records, so it falls back to the organizational domain's record at _dmarc.example.com and applies:
sp=(subdomain policy), if the record has one, orp=, if it doesn't.
So by default, subdomains simply inherit whatever p= says — including p=none, which takes no action at all. And the fallback applies to every subdomain, real or invented: a spoofer doesn't need invoices.example.com to exist in your DNS to put it in a From address.
Why spoofers like subdomains
A made-up subdomain is attractive for exactly the inheritance reason: it looks like your brand to the person reading it (security-alerts.example.com), no legitimate mail from it will ever conflict, and if your policy is still p=none it sails through with nothing but a line in your aggregate reports. Alignment doesn't save you here — with default relaxed alignment, the attacker doesn't pass either, but none means "deliver anyway."
The useful trick: lock subdomains down before the root
Here's what makes sp= practical rather than trivia. Rolling out p=reject on your main domain takes weeks of monitoring, because real mail flows through it. But if you never send from subdomains, there's nothing to break there — you can enforce that half on day one:
v=DMARC1; p=none; sp=reject; rua=mailto:reports@example.com
Root domain: still monitoring, nothing blocked yet. Every subdomain, existing or invented: spoofing rejected outright. When the root is ready, tighten p= and drop the now-redundant sp= (subdomains fall back to p=reject anyway).
The reverse direction exists too — some organizations run p=reject; sp=none while a subdomain sender is still being fixed — but treat that as a temporary exception, not a destination: it advertises your softest spot in a public DNS record.
Before you set sp=reject: check who sends from subdomains
The one way this bites is a legitimate tool quietly sending with a subdomain From address — noreply@app.example.com, alerts@status.example.com. Two checks:
- Your aggregate reports list the exact From domain per source. Run a couple of weeks on
p=noneand look for any row where the header-from is a subdomain. If there are none,sp=rejectis free. - Don't confuse bounce subdomains with From subdomains. ESP setups often use
bounce.example.comas the return-path for SPF alignment. DMARC policy applies to the visible From domain, not the return path — a bounce subdomain doesn't need its own DMARC treatment and won't be hurt bysp=reject.
The tag family, for reference
| Tag | Applies to | Notes |
|---|---|---|
p= | The domain itself (and subdomains, as fallback) | Required. |
sp= | All subdomains | Optional. Same values: none / quarantine / reject. |
np= | Non-existent subdomains only | Newer, optional tag; honored by some receivers. sp=reject covers its main use case. |
You can build a record with any of these in our free DMARC generator, and check what a domain currently publishes with the DMARC checker.
Not sure if anything sends from your subdomains? That's precisely what aggregate reports answer — and PlainDMARC reads them for you. One plain-English weekly verdict per domain: every source, every From domain, and when you're ready to tighten.
Get a plain-English weekly DMARC verdict — create a free account