---
title: "DMARC Subdomain Policy: sp= and np= Explained"
description: "DMARC subdomain policy sets how subdomains inherit p=, sp=, and np=. See the DMARCbis tree walk, sp= vs np=, and how to stop non-existent-subdomain spoofing."
publishedAt: 2026-07-27
lastUpdatedAt: 2026-07-27
tags: ["dmarc", "dmarc-subdomain-policy", "sp-tag", "np-tag", "dmarcbis", "rfc-9989"]
faq:
  - question: "How does DMARC work with subdomains?"
    answer: "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)."
  - question: "What is the DMARC sp tag (subdomain policy)?"
    answer: "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)."
  - question: "Are DMARC records inherited by subdomains?"
    answer: "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."
  - question: "What is the DMARC np tag for non-existent subdomains?"
    answer: "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."
  - question: "Should sp= be none or reject?"
    answer: "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."
---
# 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](/learn/dmarc/) 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](/blog/how-to-create-dmarc-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.

{/* TODO: SVG flowchart — subdomain policy resolution (own record → sp= → p=). Alt: "Flowchart of how a DMARC receiver resolves subdomain policy: subdomain record, then sp=, then p=." Palette per seo-conventions.md. */}

<Callout type="warning" title="The bare p=reject footgun">

A record of just `v=DMARC1; p=reject` is processed as `sp=reject` too. So the
moment you reach enforcement on the parent, **every unsigned subdomain — your
Marketo or ESP send domain, a status page, a legacy app — is silently rejected**
unless its mail is DMARC-aligned. The fix is not to back off the parent. It is
to set `sp=` intentionally.

</Callout>

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.

<KeyStat
  stat="57.9%"
  label="of DMARC-protected domains sit at p=none — and with no sp= set, every subdomain inherits that do-nothing policy"
  source="State of Email Authentication 2026 — 5,499,028 Tranco domains, scan February 27, 2026"
  sourceHref="/research/email-authentication/"
/>

## 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:

<CodeBlock
  filename="DNS TXT record — _dmarc.example.com"
  lang="dns"
  code={spNpExamples}
/>

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](/blog/dmarc-policy-not-enabled-fix/) on the
parent.

## The np= tag — policy for non-existent subdomains (DMARCbis, RFC 9989)

The `np=` tag, introduced in DMARCbis
([RFC 9989](https://www.rfc-editor.org/rfc/rfc9989.html) §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)](/blog/dmarc-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](https://support.google.com/a/answer/2466580) states that subdomains
inherit the parent policy and that `sp=` overrides it, with an explicit
subdomain record winning over both.
[Microsoft](https://learn.microsoft.com/en-us/defender-office-365/email-authentication-dmarc-configure)
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:

1. **A different policy** than the parent — for example, a subdomain still in
   monitoring while the parent enforces.
2. **A separate `rua`/`ruf` reporting destination** — the chief practical effect
   of a subdomain record is redirecting where reports go, not "adding
   protection."
3. **Delegated ownership** — a contractor- or team-managed subdomain that needs
   to control its own record.
4. **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=

1. **Look up your current DMARC record.** Run
   `dig +short TXT _dmarc.example.com` (replace `example.com` with your domain).
   Note whether `sp=` and `np=` are present and what `p=` is. A bare `p=reject`
   already behaves as `sp=reject`.
2. **Choose your subdomain policy (`sp=`).** Set `sp=reject` if no subdomains
   send legitimate mail; use `sp=none` only while a subdomain is mid-rollout and
   not yet DMARC-aligned.
3. **Add `np=` for non-existent subdomains.** Append `np=reject` as
   defense-in-depth. Receivers that ignore it fall back to `sp=`, then `p=`, so
   there is no downside to publishing it.
4. **Publish and verify.** Update the single `_dmarc` TXT 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=](/tools/dmarc-generator/).

## 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](/tools/dmarc-checker/) —
free, no signup required.