Blog · Dmarc

Why Your DMARC p=reject Policy Doesn't Protect Subdomains (And How to Fix It)

Your DMARC record says p=reject. Your domain is protected. Case closed - right?

Not quite. If you set p=reject without adding the sp= parameter, your subdomains are still fair game for spoofing.

The gap is common, partly because sp= is optional in the RFC, and partly because most people setting up DMARC for the first time copy a template, get p=reject working on the main domain, and move on. The subdomain gap doesn't show up until after an incident.

What p=reject Actually Covers

DMARC p=reject tells receiving servers to reject any email that fails authentication for the domain in the From header. That From header is the address recipients see in their email client.

When a receiving server evaluates your DMARC policy, it checks the domain in the From header against your SPF and DKIM results. If both fail alignment, the message gets rejected. But this evaluation is scoped to the exact domain in the From header.

p=reject does not automatically extend to subdomains. If someone sends from attacker@subdomain.yourdomain.com, DMARC evaluates subdomain.yourdomain.com - not yourdomain.com.

What the sp= Parameter Does

The sp= tag in your DMARC record sets the policy for subdomains explicitly. It stands for "subdomain policy."

Without it, your DMARC record applies only to the exact domain it was published on. A record published on _dmarc.yourdomain.com covers yourdomain.com. It makes no statement about subdomains - they are effectively uncovered unless you add sp= to say otherwise.

Here's the minimal complete DMARC record for full coverage:


v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc-reports@yourdomain.com; pct=100

  • **p=reject** - policy for the main domain
  • **sp=reject** - policy for all subdomains (the piece most people skip)
  • **rua** - where to send aggregate reports
  • **pct=100** - reject 100% of failing messages, not a sample

The Undelegated Subdomain Scenario

This is the part that catches most people.

An "undelegated subdomain" is a subdomain that exists in DNS but has no mail server, no web hosting, and no active services. Your organization never set it up for email - it just exists in DNS because someone registered it once.

Attackers look for these. They register an undelegated subdomain, add SPF and DKIM records, and send email from attacker@subdomain.yourdomain.com.

Here's what happens next:

The From header says subdomain.yourdomain.com. SPF passes because the attacker controls the sending infrastructure. DKIM might pass because they signed with their own key. DMARC evaluates subdomain.yourdomain.com and looks for a DMARC record on that subdomain. Finds nothing. Falls back to _dmarc.yourdomain.com. Since the main domain record has no sp= tag, it makes no statement about subdomains. The DMARC check passes. The message lands in the inbox.

The attacker has spoofed your brand from a subdomain you didn't use for email - and your p=reject policy never triggered.

This is the specific sequence behind a real client incident. The client had p=reject set. The attacker's subdomain ran for two weeks before anyone noticed.

How to Check If Your Policy Covers Subdomains

Run two DNS queries:


dig _dmarc.yourdomain.com TXT +short

dig _dmarc.subdomain.yourdomain.com TXT +short

If the second query returns nothing, your subdomains have no explicit DMARC policy. If the first query shows a record without sp=, your main domain policy says nothing about subdomains - they are effectively uncovered.

What to Look For in Your DMARC Reports

Your aggregate reports tell you which domains are sending mail as your brand. Look for subdomain.yourdomain.com appearing as a sending source.

If you see subdomains in your DMARC reports that you don't recognize as authorized senders, those are spoofing attempts - or senders you forgot to account for. Either way, they represent a gap.

DMARC reports arrive as XML. The sending domain field is easy to misread when scanning manually. DMARCFlow parses the source domain field specifically, so you can see at a glance which subdomains are generating auth failures and which have no legitimate reason to appear in your reports at all.

How to Fix the Gap

  1. Add sp=reject to your DMARC record
  2. Set pct=100 once you've confirmed your legitimate senders are all aligned
  3. Monitor aggregate reports for 30 days to catch any authorized subdomains you didn't know were sending
  4. For subdomains that legitimately send through different providers, either add explicit DMARC records for each or ensure they're covered by sp= in your main record

The goal is no surprises in your DMARC reports. Every subdomain that appears should be one you recognize.

Frequently Asked Questions

**Does sp=reject affect subdomains that have their own DMARC records?**

No. A subdomain with its own DMARC record is evaluated against that record. sp=reject in your main domain record applies only to subdomains without their own explicit policy.

**What if I only use subdomains for web hosting, not email?**

An undelegated subdomain - one with no MX record and no legitimate email flow - is exactly the type attackers target. Even if you don't use a subdomain for email, it should be covered by sp=reject. An attacker can register it, add mail infrastructure, and send from it.

**What does pct=100 mean?**

pct=100 rejects 100% of messages that fail DMARC alignment. Without it, the RFC default samples failures rather than rejecting them all. Most production environments should set pct=100 once alignment is confirmed.

**I already have sp=reject. Am I fully covered?**

If sp=reject is present and your aggregate reports show no unexpected subdomain activity, you're covered. Review reports periodically - new subdomains appear as infrastructure changes, and each new one that sends mail is a potential gap until you confirm it's authorized.