DMARC Subdomain Policy: How sp= and np= Protect Every Subdomain
A p=reject policy on your root domain does nothing for mail.example.com —
unless you tell DMARC what to do with subdomains.
A DMARC subdomain policy is the rule a domain owner publishes for mail sent
from subdomains of an organizational domain. It is controlled by two tags:
sp= (for existing subdomains) and np= (for non-existent subdomains, added in
DMARCbis / RFC 9989). When you set neither, subdomains inherit the parent
domain’s p= policy.
This post assumes you already know the basics. If you do not, start with our
DMARC fundamentals guide and come back. Most subdomain spoofing
succeeds because the parent domain left sp= and np= unset, so a do-nothing
p=none quietly covers every subdomain too.
Here is what to publish, and why: how a subdomain policy resolves, sp= versus
np=, the DMARCbis DNS tree walk, whether receivers actually honor these tags,
and the exact record to set.
What is the DMARC sp tag (subdomain policy)?
The sp= tag sets the DMARC policy for mail from existing subdomains of your
organizational domain. It takes the same three values as p= — none,
quarantine, or reject — and lives in the parent domain’s _dmarc record. If
you omit sp=, subdomains use whatever p= is set to.
Two details matter. First, the organizational domain is the registrable
domain at the top of your namespace — example.com, not mail.example.com.
Second, sp= is only meaningful on the organizational domain’s record. RFC 9989
§4.7 states that sp= “will be ignored for DMARC Policy Records published on
subdomains,” so putting sp= on _dmarc.mail.example.com does nothing — set it
on the parent.
Here is how the three policy tags relate:
| Tag | Applies to | Values | Default when unset |
|---|---|---|---|
p= | the organizational domain itself | none / quarantine / reject | treated as none if missing |
sp= | existing subdomains | none / quarantine / reject | falls back to p= |
np= | non-existent subdomains | none / quarantine / reject | falls back to sp=, then p= |
For the full DMARC tag grammar and how to publish the record itself, see the full DMARC tag reference and how to publish the record. The rest of this guide is about behavior: how those tags resolve and how to use them to close a spoofing gap.
How subdomains inherit the DMARC policy
Subdomains do not need their own DMARC record. A receiver applies the most
specific policy it finds, in this order: (1) the subdomain’s own _dmarc record
if one exists, otherwise (2) the parent’s sp= value, otherwise (3) the
parent’s p= value. RFC 9989 §4.10.1 spells out exactly this precedence.
Walk it through with example.com. Suppose the parent publishes
v=DMARC1; p=reject; sp=quarantine. Mail from news.example.com, which has no
record of its own, is quarantined on failure (the sp= value). Mail from
shop.example.com, which publishes its own _dmarc record with p=none, is
governed by that record — the subdomain’s own policy wins.
This inheritance is also why a permissive parent leaves subdomains exposed. If
p=none is in place and sp= is unset, no subdomain is protected either.
57.9% of DMARC-protected domains sit at p=none — and with no sp= set, every subdomain inherits that do-nothing policy
sp=none vs sp=reject — subdomain policy examples
Use sp=reject when no subdomains send legitimate mail (the common case). Use
sp=none only when a subdomain sends mail that is not yet DMARC-aligned and you
are still in monitoring mode. The two configurations below look similar and
behave very differently:
# Root protected, subdomains WIDE OPEN — the exposed combination
v=DMARC1; p=reject; sp=none
# Root in monitoring, subdomains locked down — protect inactive
# subdomains while you still test the parent policy
v=DMARC1; p=none; sp=reject The first record protects the root and leaves subdomains wide open — the exposed one, and the exact gap attackers look for. The second puts the root in monitoring while locking down subdomains, which is useful when you want to protect inactive subdomains before the parent reaches enforcement.
If you have no legitimate subdomain senders, the strongest posture is
sp=reject paired with np=reject (covered next). Getting subdomains to
enforcement is part of reaching a domain-wide p=reject — the same journey as
moving from p=none to enforcement on the
parent.
The np= tag — policy for non-existent subdomains (DMARCbis, RFC 9989)
The np= tag, introduced in DMARCbis
(RFC 9989 §4.7), sets the DMARC
policy for mail claiming to come from subdomains that do not exist in DNS. It
takes none, quarantine, or reject. If np= is unset, the receiver falls
back to sp=, then to p=.
Here is the attack it closes. A spoofer invents a subdomain that was never
created — random-invoice.brand.com, payroll.brand.com — that has no _dmarc
record. Under the original 2015 DMARC specification there was no dedicated
control for this, and receiver fallback behavior diverged — DMARCbis (RFC 9989
§4.7) added the np= tag. A 2021 peer-reviewed study
(Maroofi et al., IEEE Transactions on Network and Service Management) showed
attackers could spoof every tested provider from non-existent subdomains when
the organizational domain set no subdomain policy. np=reject is the IETF’s
purpose-built answer.
The clearest real-world demonstration is gov.uk. As documented by Hexiosec
(formerly Red Maple) in 2022, _dmarc.gov.uk publishes
p=reject; sp=none; np=reject; adkim=s; aspf=s; fo=1, while _dmarc.data.gov.uk
does not exist. The np=reject blocks the non-existent-subdomain spoof that the
permissive sp=none would otherwise have let through.
One thing np= does not fix: hijacked subdomains that genuinely exist. In
the February 2024 SubdoMailing campaign (Guardio Labs), attackers re-registered
abandoned domains behind dangling CNAME and stale SPF records of real brands, so
their mail passed SPF, DKIM, and DMARC from existing, hijacked subdomains. np=
addresses only non-existent subdomains; the fix for that class is DNS hygiene —
removing dangling records and stale include: entries.
How the DMARCbis DNS tree walk finds your subdomain policy
To decide which policy applies, a DMARCbis receiver performs a DNS tree walk: it starts at the sending subdomain and queries progressively higher labels — up to a maximum of eight lookups — until it finds a DMARC record (RFC 9989 §4.10). This replaces the deprecated Public Suffix List (PSL) two-query method that older guides still teach. A “non-existent” subdomain is defined precisely: a DNS query that returns NXDOMAIN (RFC 9989 §3.2.13). One honest caveat: the tree walk and the PSL can resolve a different organizational domain for some TLDs, so the spec’s own mitigation is explicit records plus strict alignment at every sending domain.
For the wider DMARCbis picture, see the full DMARCbis breakdown (RFC 9989, 9990, 9991).
Do receivers actually honor sp= and np=?
As of June 2026, the major receivers honor sp= inheritance, but none publicly
documents support for np= or the DMARCbis tree walk. Treat sp= as enforced
and np= as defense-in-depth: safe to publish, but not yet something you can
rely on a receiver enforcing.
On sp=, the documentation is clear.
Google states that subdomains
inherit the parent policy and that sp= overrides it, with an explicit
subdomain record winning over both.
Microsoft
documents that the parent record “automatically covers all subdomains
(including nonexistent subdomains)” unless a subdomain publishes its own record.
Apple’s Branded Mail guide requires sp=quarantine or sp=reject when
registering subdomains under a parent record. Yahoo urges a policy per sending
domain but does not document sp= semantics, so its behavior is unverified.
On np= and the tree walk, the absence is the finding: no major receiver
documents either. OpenDMARC is frozen at version 1.4.2 (December 2021) and
remains PSL-based; Rspamd 4.1.1 implements neither. Only checker and library
tooling — checkdmarc and Mail::DMARC — has shipped np= parsing and the tree
walk. DMARCguard’s own checker runs the DMARCbis tree walk, so it shows which
policy a receiver should resolve for a subdomain. A second caveat: not all
authoritative nameservers return NXDOMAIN for an empty subdomain, so even where
np= is read, enforcement can be inconsistent.
The action that follows: publish np=reject now as defense-in-depth, keep
sp= set, and neutralize the tree-walk-versus-PSL gap with explicit records and
strict alignment (adkim=s; aspf=s) at every sending domain.
When should a subdomain have its own DMARC record?
Most subdomains should inherit the parent policy. Publish a separate _dmarc
record on a subdomain only when you need one of four things:
- A different policy than the parent — for example, a subdomain still in monitoring while the parent enforces.
- A separate
rua/rufreporting destination — the chief practical effect of a subdomain record is redirecting where reports go, not “adding protection.” - Delegated ownership — a contractor- or team-managed subdomain that needs to control its own record.
- A staged enforcement rollout scoped to that one subdomain.
There is a governance trap here. A subdomain owner who publishes p=none on a
delegated subdomain re-opens a spoofing hole the parent had already closed. At
scale, decide deliberately who can publish subdomain records.
Parked and non-sending domains need the least deliberation: with no mail
expected anywhere, the strongest posture is p=reject; sp=reject; np=reject.
Creating the record itself is no different from any DMARC record — the TXT host
is _dmarc.<subdomain> and the syntax is identical. This page stays on
behavior and policy.
How to set a DMARC subdomain policy with sp= and np=
- Look up your current DMARC record. Run
dig +short TXT _dmarc.example.com(replaceexample.comwith your domain). Note whethersp=andnp=are present and whatp=is. A barep=rejectalready behaves assp=reject. - Choose your subdomain policy (
sp=). Setsp=rejectif no subdomains send legitimate mail; usesp=noneonly while a subdomain is mid-rollout and not yet DMARC-aligned. - Add
np=for non-existent subdomains. Appendnp=rejectas defense-in-depth. Receivers that ignore it fall back tosp=, thenp=, so there is no downside to publishing it. - Publish and verify. Update the single
_dmarcTXT record on the organizational domain — not on a subdomain — then confirm it is live.
A hardened end-state record reads:
v=DMARC1; p=reject; sp=reject; np=reject; rua=mailto:dmarc@example.com; adkim=s; aspf=s.
You can build one with our
DMARC generator with sp= and np=.
Frequently Asked Questions
How does DMARC work with subdomains?
Subdomains inherit the organizational domain’s DMARC policy unless overridden. A
receiver applies the subdomain’s own _dmarc record if one exists, otherwise the
parent’s sp= value, otherwise the parent’s p=. No separate record is required
for inheritance to work (RFC 9989, Section 4.10.1).
What is the DMARC sp tag (subdomain policy)?
The sp= tag sets the DMARC policy for existing subdomains of the organizational
domain, using the same none, quarantine, or reject values as p=. It is
published on the parent’s _dmarc record and, when omitted, defaults to the p=
value (RFC 9989, Section 4.7).
Are DMARC records inherited by subdomains?
Yes. If a subdomain has no _dmarc record, receivers apply the parent’s sp=
policy, or the parent’s p= if sp= is unset. A bare p=reject therefore also
rejects unsigned subdomain mail, so set sp= intentionally to avoid surprising
your own senders.
What is the DMARC np tag for non-existent subdomains?
np=, added in DMARCbis (RFC 9989), sets the policy for mail from subdomains
that do not exist in DNS — a common spoofing vector. It takes none,
quarantine, or reject and defaults to sp=, then p=. Major receivers do
not yet document np=, so treat it as defense-in-depth.
Should sp= be none or reject?
Use sp=reject when no subdomains send legitimate mail — the strongest and most
common posture. Use sp=none only while a subdomain’s mail is not yet
DMARC-aligned and you are monitoring. Pair sp=reject with np=reject on parked
domains that have no subdomain senders.
Conclusion
Subdomains inherit p= unless sp=, np=, or an explicit record overrides it.
np=reject is the DMARCbis (RFC 9989) fix for non-existent-subdomain spoofing,
but it is not yet enforced at major receivers — publish it as defense-in-depth,
not as a control to rely on. The durable posture is explicit records plus strict
alignment at every sending domain.
Set your DMARC subdomain policy deliberately, then verify it. Check what policy a receiver resolves for your subdomains — free, no signup required.