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, or
  • p=, 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:

  1. Your aggregate reports list the exact From domain per source. Run a couple of weeks on p=none and look for any row where the header-from is a subdomain. If there are none, sp=reject is free.
  2. Don't confuse bounce subdomains with From subdomains. ESP setups often use bounce.example.com as 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 by sp=reject.

The tag family, for reference

TagApplies toNotes
p=The domain itself (and subdomains, as fallback)Required.
sp=All subdomainsOptional. Same values: none / quarantine / reject.
np=Non-existent subdomains onlyNewer, 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