Blog · Dmarc

Why the DMARC np Tag Does Not Work When DNSSEC Is Enabled

What the DMARC np tag is

RFC 9989, published in May 2026, added a new tag to the DMARC specification: np (nonexistent policy). It lets domain owners set a handling policy specifically for mail sent from subdomains that do not exist.

Before np, if you wanted a reject policy for all subdomains you had to publish sp=reject and accept that it applied everywhere, including subdomains you had no direct control over. The np tag was designed to fill that gap. You could publish p=quarantine for the apex domain while setting np=reject for subdomains that should never send mail.

It is a clean idea. In practice, it breaks on any domain running DNSSEC.

How DNS negative responses work without DNSSEC

When a DNS resolver asks for a record that does not exist, the authoritative DNS server responds with an NXDOMAIN response code (rcode = 3). This tells the resolver: nothing here, move on.

For DMARC policy discovery, when a receiving server checks _dmarc.example.com and gets NXDOMAIN, it concludes there is no DMARC record for that subdomain. Under RFC 9989, it should then look at the np tag in the parent domain's record to decide what to do with the message.

This logic depends entirely on receiving NXDOMAIN.

What DNSSEC changes

DNSSEC signs DNS records cryptographically. When you enable DNSSEC, the DNS response behavior for non-existent records changes in a specific and important way.

Instead of NXDOMAIN, a DNSSEC-enabled zone returns NOERROR (rcode = 0) with an NSEC record or NSEC3 record that provides cryptographic proof that the record does not exist. The response code is no longer 3 (NXDOMAIN). The absence of the record is proved using signed chain of NSEC or NSEC3 records.

The key point: with DNSSEC, "this record does not exist" is communicated through a NOERROR response plus a proof of denial, not through an NXDOMAIN code.

Where the np tag breaks

RFC 9989's np tag assumes the receiving DMARC validator will receive NXDOMAIN when a subdomain does not exist. Many existing DMARC implementations were written against that assumption. They look for NXDOMAIN as the signal to fall back to the np policy.

A DMARC validator that validates DNSSEC itself, or that sits behind a resolver that performs DNSSEC validation, may receive NOERROR plus NSEC/NSEC3 instead. If that validator was not written to treat NOERROR plus empty answer plus NSEC/NSEC3 as equivalent to NXDOMAIN for DMARC purposes, it will not apply the np policy correctly. In some implementations it skips the np policy entirely. In others it generates a temporary failure rather than applying the intended policy.

This is not theoretical. The r/DMARC discussion that surfaced this issue notes that Cloudflare, AWS Route 53, Azure DNS, and Google Cloud DNS all support DNSSEC, and all of them return NOERROR plus NSEC/NSEC3 for non-existent records in DNSSEC-enabled zones. Any receiver that validates DNSSEC or queries through a DNSSEC-validating resolver may get a different result than the sender's np tag intended.

Which DNS providers are affected

The major DNSSEC-enabled providers all return the same NOERROR plus NSEC/NSEC3 response for non-existent records:

  • Cloudflare (DNSSEC enabled by default)
  • AWS Route 53 (DNSSEC available, must be explicitly enabled)
  • Azure DNS (DNSSEC available)
  • Google Cloud DNS (DNSSEC available)

If your DMARC record is hosted on any of these and you have enabled DNSSEC, your np tag may not work as intended for receivers that also validate DNSSEC.

What to do today

There is no single fix that resolves this at the protocol level today. Here is what you can do practically.

1. Do not rely solely on np for critical subdomain policies

If you need a reject policy for subdomains that should never send mail, use an explicit sp=reject record on those specific subdomain zones rather than relying on np in the parent record. Explicit subdomain DMARC records are processed directly and do not depend on np behavior at all.

2. Test across multiple receivers

Send test messages from a non-existent subdomain to receivers known to use DNSSEC-validating resolvers. Compare the results. If some receivers apply your np policy and others do not, you have confirmation of the issue.

This is where DMARCFlow is most directly useful. Instead of manually collecting and normalizing aggregate reports from dozens of receivers, DMARCFlow pulls them into a single view and flags receivers that are handling your np policy differently from what your record specifies. If three major receivers honor np but one silently ignores it, DMARCFlow surfaces that inconsistency immediately rather than waiting for a user complaint.

3. Monitor your DMARC reports for inconsistencies

DMARC aggregate reports show you what individual receivers actually do with your mail. If your np policy is being applied inconsistently across receivers, you will see it as anomalous pass/fail patterns that do not match your record's intent. Services that aggregate and normalize these reports across many receivers can surface this faster than manual review.

4. Watch for validator updates

This is a young incompatibility. Validator implementers are still working through the implications of RFC 9989 on DNSSEC-enabled zones. Watch for updates from major DMARC receiving organizations and validators. The fix will come from the validator side, not the sender side.

How DMARCFlow helps

DMARCFlow monitors your DMARC aggregate reports continuously and flags inconsistencies in how receivers handle your messages. If your np policy is silently ignored by some receivers due to DNSSEC, DMARCFlow surfaces those receivers so you can investigate before a deliverability problem becomes a broader email perception problem. For np tag specifically, the value is in the cross-receiver comparison: seeing at a glance which receivers apply the policy and which do not, without manually parsing raw DMARC XML.

FAQ

What is the np tag in DMARC?

The np tag (nonexistent policy) in DMARC RFC 9989 sets a handling policy for mail sent from subdomains that do not exist. It lets domain owners specify a different policy for non-existent subdomains than for the apex domain.

Why does DNSSEC break the np tag?

The np tag was designed around the assumption that non-existent subdomains return an NXDOMAIN DNS response code. DNSSEC changes this: non-existent records return NOERROR with NSEC or NSEC3 records as cryptographic proof of absence, not NXDOMAIN. Some DMARC validators do not treat this as equivalent to NXDOMAIN, so they do not apply the np policy correctly.

Which DNS providers does this affect?

Cloudflare, AWS Route 53, Azure DNS, and Google Cloud DNS all use DNSSEC and return NOERROR plus NSEC/NSEC3 for non-existent records. Any domain using DNSSEC on these providers may be affected.

Should I disable DNSSEC for my DMARC record?

Disabling DNSSEC removes DNSSEC protection for your domain's DNS records, which is not a small thing. A better approach is to use explicit subdomain DMARC records with sp= rather than relying on np, and to monitor your DMARC reports for inconsistencies.

What can I use instead of np if DNSSEC is enabled?

Use explicit subdomain DMARC records. Publish a v=DMARC1; p=reject; record in each subdomain zone that should send mail, and publish sp=reject at the parent level where appropriate. Explicit records do not depend on np behavior at all.

Sources