Most DMARC conversations focus on a single letter: the p= policy on the organisational domain. Audits check it, compliance frameworks ask for it, and vendor dashboards celebrate the day it reaches reject. But DMARC has a second policy knob that rarely gets the same attention: sp=, the subdomain policy. When it is present and weaker than p=, the organisation has — usually deliberately, at some point, for some reason nobody remembers — carved its entire subdomain space out of enforcement.
We parse the sp= tag across all 459,124 DMARC records in the Tranco top-1M as part of our daily email infrastructure report (first figure as of the 2026-07-05 snapshot). The split-policy pattern — strict apex, permissive subdomains — shows up often enough that it deserves its own line in any email security audit. Here is how the mechanism works and how to close the gap without breaking anything.
How subdomain policy actually resolves
When a receiver evaluates DMARC for a message from invoices.example.com, it first looks for a DMARC record at _dmarc.invoices.example.com. If none exists — and for the vast majority of subdomains none does — it falls back to the organisational domain's record at _dmarc.example.com and applies:
- the
sp=policy, if the tag is present, or - the
p=policy, if it is not.
That default is the important part: omitting sp= is safe. Subdomains inherit whatever the apex enforces. The gap only opens when someone writes an explicit weaker value:
; Apex protected, subdomains exempt — the gap:
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; sp=none; rua=mailto:dmarc@example.com"
; What it should usually say — sp= omitted, subdomains inherit reject:
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"Why sp=none gets written — and then forgotten
Nobody types sp=none by accident; the tag exists because it solves a real rollout problem. The typical history goes like this:
- Phase one: protect the brand domain first. The apex sends executive and customer-facing mail; it gets cleaned up and moved to enforcement early. Subdomains host a zoo of legacy senders — ticketing systems, regional marketing platforms, that appliance in a subsidiary — whose alignment nobody has inventoried yet. Setting
sp=nonelets the apex reachrejectwithout waiting for the zoo. - Phase two never happens. The plan was always to fix the subdomain senders and remove the tag. But the apex now passes every compliance check, the dashboard is green, the project closes, and the exemption survives — invisible unless someone reads the raw record and knows what the tag means.
- Vendor templates propagate it. Some deployment guides and legacy tooling included
sp=noneas a "cautious" boilerplate default, seeding the pattern into records whose owners never made an explicit decision at all.
What an attacker does with the gap
The subdomain gap is more useful to an attacker than it first appears, because DMARC evaluates the exact From-header domain — and the attacker chooses it. With sp=none on your apex record:
- Mail spoofed as
payroll.example.comorit-support.example.comfails authentication and is delivered anyway, policy-wise, exactly as if you had no DMARC at all. - The subdomain does not need to exist. There is no requirement that a From-header domain resolves or has ever sent mail; a fabricated subdomain inherits the same
noneexemption. - Subdomain spoofs often read as more credible than apex spoofs to targets — internal systems really do send from service-named subdomains, so
noreply@vpn.example.comlooks routine. - The whole configuration is public. The same one-query reconnaissance that reveals a p=none monitoring-only policy also reveals a strict-apex-weak-subdomain split — and tells the attacker precisely which From domains to use.
Run dig TXT _dmarc.yourdomain.com +short and read two tags, not one. If sp= is present and weaker than p=, you have a documented decision to verify or a forgotten exemption to remove. If sp= is absent, your subdomains inherit the apex policy and no action is needed.
Closing the gap safely
Removing a forgotten sp=none deserves the same staged care as any enforcement move, because it may be silently shielding a legitimate subdomain sender:
- Mine your aggregate reports by subdomain. Your
rua=data already breaks out From domains; list every subdomain that sends, and its pass rate. - Fix or fence each real sender. Align SPF and DKIM for legitimate subdomain streams; give high-risk or third-party streams their own explicit subdomain DMARC records where isolation makes sense.
- Tighten sp= in steps —
sp=quarantinebeforesp=reject, or simply delete the tag once the apex policy is where you want subdomains to land. - Re-check after every record edit. The tag has a way of reappearing when records are regenerated from stale templates.
We publish subdomain-policy parsing alongside the headline DMARC numbers every night; the current breakdown and the full policy split live in the DMARC section of the daily report. And once your apex and subdomains both enforce, the natural next rung — BIMI, MTA-STS, TLS-RPT — is covered in our adoption review of the newer standards.