The DMARC Subdomain Gap: When 'p=reject' Quietly Breaks Your Email
A parent domain's 'p=reject' policy automatically applies to all subdomains, a default inheritance that can silently block legitimate mail from unconfigured services.

You finally did it. After months of monitoring DMARC aggregate reports, you flipped your company's primary domain to `p=reject`. A clean, simple TXT record: `v=DMARC1; p=reject; rua=...`. No more spoofing of your CEO's address. You close the ticket, job well done. Two weeks later, the VP of Marketing is at your desk. The launch campaign emails from their new platform, `send.marketing.yourcompany.com`, are vanishing into thin air. No bounces, just silence.
This isn't a hypothetical. It's a common, painful scenario born from a little-understood rule in RFC 7489. Your tight security policy on the main domain just created a blind spot, and now legitimate, authenticated email is being dropped on the floor by receiving mail servers.
The culprit is DMARC's implicit policy inheritance for subdomains. If a subdomain doesn't have its own DMARC policy, it inherits the policy of its parent. And when that parent policy is `reject`, the consequences are immediate and severe.
The Ghost in the RFC: How Receivers Discover Policy
When a mail server receives a message, its DMARC validation process is a hunt for instructions. It needs to know what to do if authentication fails. As defined in RFC 7489, this hunt follows a specific, logical path.
Imagine an email arrives from `alerts@status.yourcompany.com`. The receiver's first step is to check for a DMARC policy specific to that subdomain. It performs a DNS lookup for a TXT record at `_dmarc.status.yourcompany.com`. If a valid DMARC record is found there, the game is over. That policy is used, and the parent domain's policy is ignored.
But what happens when that lookup returns `NXDOMAIN`, meaning no record exists? The receiver doesn't just give up. It climbs the DNS tree. The process is repeated for the organizational domain, `yourcompany.com`. The receiver queries `_dmarc.yourcompany.com`. If it finds a policy there, it applies *that* policy to the email from the subdomain. This is the core of subdomain policy inheritance.
This mechanism is designed for efficiency. It saves you from creating identical DMARC records for every single subdomain. However, it's also a double-edged sword. The policy you set for your primary corporate mail—which is probably locked down tight—is now the default law for every other subdomain, including the ones you might not even know are sending email.
Anatomy of an Outage: Deconstructing the Failure
Let's return to our marketing campaign disaster. The emails from `send.marketing.yourcompany.com` are correctly configured. The sending platform has its IPs in the SPF record for that subdomain (RFC 7208), and it signs with a DKIM signature (RFC 6376) aligned with `send.marketing.yourcompany.com`. From an authentication perspective, everything looks good. So why are they failing DMARC?
The answer is in the `Authentication-Results` header of a failed message, a header every security analyst should know how to read.
Authentication-Results: mta.receiver.com; dmarc=fail (p=REJECT sp=REJECT) header.from=send.marketing.yourcompany.com; dkim=pass header.d=send.marketing.yourcompany.com; spf=pass (sender IP is 203.0.113.50) — Example Authentication-Results Header
Let's break that down. `dkim=pass` and `spf=pass` confirm that the basic authentication checks succeeded. The server is who it claims to be. But the crucial part is `dmarc=fail`. The policy decision `(p=REJECT sp=REJECT)` tells us exactly what policy was applied. The receiver found no DMARC record for the subdomain, so it used the parent's policy, which is `p=reject`. The `sp=REJECT` here reflects the same; since no subdomain policy tag was specified, it defaults to the `p=` value.
The Alignment Mismatch
The final nail in the coffin is alignment. DMARC doesn't just check if SPF and DKIM pass; it checks if the domain used for those passes *aligns* with the domain in the `From:` header. Your parent policy at `_dmarc.yourcompany.com` almost certainly requires alignment with `yourcompany.com`. But the DKIM signature was aligned with `send.marketing.yourcompany.com`. Since `send.marketing.yourcompany.com` does not match `yourcompany.com` in a strict alignment check, DMARC fails. The passing authentication checks are irrelevant because they don't meet the policy's alignment criteria. Result: `reject`.
Two Paths to a Fix: Explicit Subdomain Control
Once you've diagnosed the problem, you have two primary ways to fix it. Both involve creating DNS records to give receivers explicit instructions, overriding the dangerous implicit inheritance.
The Surgical Strike: Using the 'sp=' Tag
The simplest and broadest solution is to modify your parent domain's DMARC record with the `sp=` (subdomain policy) tag. This tag explicitly declares the policy that should be applied to any subdomain that does not have its own DMARC policy.
By changing your record to `v=DMARC1; p=reject; sp=none; rua=...`, you tell the world: 'For mail from `yourcompany.com`, enforce `reject`. For mail from *any* of my subdomains, take no action.' This immediately stops the bleeding. Your marketing emails will start flowing because receivers will now apply a `p=none` policy to them, effectively ignoring DMARC failures while you continue to gather data via RUA reports.
The Granular Approach: A Per-Subdomain Policy
The second option is more targeted. Instead of a blanket policy for all subdomains, you can create a DMARC record for the specific subdomain that is sending mail. In our scenario, you would create a new TXT record:
`_dmarc.send.marketing.yourcompany.com IN TXT "v=DMARC1; p=none;"`
When a receiver looks up policy for mail from this subdomain, it finds this record first and stops. It never checks the parent domain. This approach gives you granular control. You can set `p=none` for the marketing platform while another subdomain, like `billing.yourcompany.com`, might have its own `p=reject` policy. It's more management overhead but is the technically correct path for organizations with complex, multi-vendor email ecosystems.
Playbook for Auditing the Subdomain Gap
You can't fix what you can't see. Before you move to `p=reject`—or if you already have—you must audit for subdomains that send mail. Proactive discovery prevents outages.
Start with DMARC Reports
Your DMARC aggregate (RUA) reports are the absolute source of truth. Parse these XML files and look at the `header_from` field in every record. Build a unique list of all subdomains seen sending email claiming to be from your domain. This will quickly reveal third-party senders and internal systems you weren't aware of.
Perform DNS and Certificate Reconnaissance
Actively search for subdomains. Certificate Transparency (CT) logs are a goldmine. Using a service like `crt.sh`, you can search for `%.yourcompany.com` to find issued certificates for subdomains, many of which may be associated with cloud services that send email. Once you have a list of potential subdomains, query each one for MX, SPF, and TXT records to identify signs of email activity.
Interview Internal Teams
Go talk to people. Ask your marketing, sales, finance, and HR departments what SaaS platforms they use. Zendesk, Salesforce, Workday, Mailchimp, Stripe—they all send email on your behalf, and they often do it from a subdomain. Their setup guides are the first place to look for the correct SPF and DKIM configuration.
Why 'sp=quarantine' Is a Smart Intermediate Step
Jumping straight from nothing to `sp=none` or `sp=reject` can feel abrupt. For organizations with a low tolerance for risk and a lot of legacy systems, the `sp=quarantine` tag offers a valuable middle ground.
Setting `v=DMARC1; p=reject; sp=quarantine;` on your parent domain provides a safety net. Mail from your properly configured apex domain is protected by `reject`, while unaligned mail from a forgotten subdomain will be sent to the spam folder instead of being dropped entirely. This gives users a chance to find important messages (like password resets or invoices) that might otherwise have vanished.
Using `quarantine` for subdomains allows you to see the impact of enforcement in your DMARC reports without causing a full-blown outage. It's a powerful signal that something is wrong, prompting investigation without bringing business processes to a halt. Once you've identified and configured all legitimate subdomain senders, you can then confidently move them to their own `p=reject` policies or maintain `sp=none` as your default if they are not supposed to send mail.
The takeaway
DMARC policy inheritance is a feature, not a bug, but it demands respect. Assuming your subdomains are exempt from your apex domain's `p=reject` policy is a recipe for silent failure. The operational stake is simple: legitimate, business-critical email will be thrown away by recipients, and you won't get a bounce message to tell you it happened.
The only way to safely deploy `p=reject` at your organizational domain is to explicitly declare your intent for subdomains. Always set an `sp=` tag. Start with `sp=none` or `sp=quarantine`, use your aggregate reports to find and fix every sender, and methodically work toward total coverage. Manually parsing DMARC reports to find these gaps can be tedious; tools like MailSleuth.AI can automate the discovery of sending subdomains and highlight alignment failures before they become incidents.
We dissect phishing campaigns and email infrastructure so you don't have to.


