DMARCbis: The DNS Tree Walk and Why np Doesn't Always Fire on DNSSEC Domains

Part 3 of the DMARCbis series. Start with the overview.
The previous part covered the tag changes. This time we look at what the psd tag is actually for, and the trouble np runs into on DNSSEC-signed domains. Both hang on the same mechanism, the DNS Tree Walk, which replaces the Public Suffix List in DMARCbis.
Sounds like a big deal. For most domains, though, nothing changes in the result. It gets interesting in exactly two places.
What the Tree Walk replaces, and why
For every incoming mail, DMARC has to answer one question: which domain is the Organizational Domain, meaning the registrable level where policy and alignment are anchored? For newsletter@mail.example.com that is not automatically mail.example.com, but usually example.com. The catch: how does a Receiver know the boundary between registrable domain and public suffix sits exactly there and not at .com?
RFC 7489, the 2015 state of DMARC, solved this with a Public Suffix List, an externally maintained list of all public suffixes. In practice that had weak spots. The old standard prescribed no particular list, gave no guidance on how often a Receiver should update it, and admitted itself that different Receivers with different lists can cause interoperability problems. Even back then the RFC text said a more reliable method should replace the PSL once one exists.
That method is the DNS Tree Walk. Instead of looking things up in a list, Receivers walk the DNS tree themselves, label by label, looking for a valid DMARC record. The Organizational Domain follows from what the walk finds along the way.
How the walk works
The process is straightforward. The Receiver first queries _dmarc. on the starting name, then drops the leftmost label and queries one level up, on and on toward the root. For a.mail.example.com that means, in order, _dmarc.a.mail.example.com, _dmarc.mail.example.com, _dmarc.example.com, _dmarc.com.
Since every step is a DNS query, an attacker could overload a Receiver with deliberately deeply nested sender domains. So there is a brake built in: the walk stops after at most eight queries, even for domains with more labels. Eight is a deliberate choice. Per RFC 9989, section 4.10, sender domains with up to seven labels were in use at the time of publication, and the eighth query is headroom.
The walk can also stop earlier. If it finds exactly one valid record with psd=y or psd=n at a level, it halts right there. Without such a signal it keeps going until no labels are left. Which brings us to the actual point.
What psd is really for
psd stands for Public Suffix Domain. The tag has three possible values, each governing a different situation.
psd=n means: "I am the Organizational Domain, stop here." The walk stops, this domain is the Org domain. The practical effect: if a public suffix above your domain has accidentally published a DMARC record without the correct psd=y, you can use psd=n on your own record to stop a Receiver from wrongly pulling that higher record for you. You draw the boundary yourself.
One critical point: a DMARC record on your own domain does not stop the walk automatically. The RFC separates two processes. For the policy: if the Receiver finds a record directly on your sender domain, it takes that policy and does not look further up (RFC 9989, section 4.10.1). For relaxed alignment, however, it also has to determine the Organizational Domain, and that Org domain walk keeps climbing past your own record as long as your record carries no psd signal (section 4.10.2). Without a signal it collects what it finds along the way and, in the end, picks the record with the fewest labels. If a misconfigured record without psd=y sits above you, that one can win and push your Org domain upward. Only psd=n on your record stops the walk at you, before it even queries the higher record.
So is it worth setting psd=n on your own root domain as a precaution, on the logic of "set it once, stay safe"? In most cases, no. Under .com or .org the suffix level publishes no DMARC record at all, the walk finds nothing up there and returns your domain correctly anyway via "fewest labels." psd=n then saves you one query at most and changes nothing in the result. It is only needed in the special case where you sit under a suffix that has set a record without a correct psd=y. Two things to keep in mind if you do. First, psd=n belongs only on the actual Organizational Domain, your registrable root domain, never on a subdomain. Set on _dmarc.mail.yourdomain.com, you would wrongly declare mail.yourdomain.com its own Org domain and wreck relaxed alignment between the subdomain and the root. Second, psd=n is not a safety switch but a boundary declaration that only does anything in certain topologies. There is no "set and forget" here.
psd=y is the counterpart, set by suffix operators under which independent organizations register directly. If the walk finds a record with psd=y, it also stops, but the Organizational Domain is then not that record itself, it is the level one label below. Example: if several independent parties register directly under a shared suffix, the default would collapse them all onto the same Org domain, and alignment between two genuinely separate organizations would break. psd=y pushes the boundary one level down and keeps them apart. One exception in the RFC: the rule does not apply when the psd=y record happens to be the one for the starting domain itself.
psd=u is the default and the normal case. No signal in either direction. The walk runs all the way through and then picks the valid record with the fewest labels as the Org domain. If it finds no record at all, the original sender domain is the Org domain itself.
And since psd=u is the default: don't write it out. A tag you leave off automatically takes its default value, spelling out psd=u gains you nothing technically and only makes the record longer. That is a good rule of thumb for DMARC records in general: optional tags left at their default value do not belong in the record. Shorter records read better and are easier to check, and you lose nothing.
For most nothing changes, for a few it does
For a flat domain, example.com with a handful of subdomains, the Tree Walk lands on exactly the Org domain the old PSL would have returned too. Hence the repeated note: nothing to do, no DNS change needed.
Divergence does not arise from simple nesting. A normal structure like a.division.bigcorp.com yields the same Org domain bigcorp.com under both PSL and Tree Walk, because "fewest labels" lands exactly where the PSL draws the line too. The two only diverge where PSL and DNS tree disagree about the suffix boundary. As in Post 2, I will shorten the two camps: 7489-Receiver (still on PSL) and 9989-Receiver (already on Tree Walk).
A concrete example. Alongside the real TLDs, the PSL has a private section for platform suffixes under which third-party customers register their own names, such as github.io or vercel.app (source: publicsuffix.org). The point: a.github.io and b.github.io should count as separate organizations, not as one. Take such a platform, example-hosting.com, with two customers, customer-a.example-hosting.com and customer-b.example-hosting.com.
A 7489-Receiver knows
example-hosting.comas a suffix from the private PSL section and treats the two customers as separate Org domains.A 9989-Receiver no longer consults any PSL. If the platform has not published
psd=yonexample-hosting.com, its walk runs up toexample-hosting.comand turns that into a shared Org domain for both customers via "fewest labels."
Now a mail arrives from info@customer-a.example-hosting.com, but DKIM-signed with d=customer-b.example-hosting.com, that is, with another customer's signature. For the 7489-Receiver, Org domain(customer-a...) is not equal to Org domain(customer-b...), so not aligned, DKIM contributes nothing. For the 9989-Receiver, both collapse onto example-hosting.com, so aligned, DKIM fits.
Same mail, two outcomes, and in the wrong direction: the 9989-Receiver lets a mail signed across customer boundaries pass as aligned, which the PSL-Receiver stops. One customer could borrow another's alignment this way. This is exactly the gap that psd=y closes, the one the platform has to set on example-hosting.com. With strict alignment none of this happens, because there the comparison is exact and no Org domain comparison takes place at all. Anyone who hands out customer subdomains as a platform operator, or sits on such a platform as a customer and runs relaxed, should keep this on their radar.
The np trap on DNSSEC
The second point from the teaser, and the trickier one in practice. A quick reminder from Post 2: np sets a separate policy for non-existent subdomains, so that spoofing over made-up names runs into nothing. The catch is in the definition of "non-existent." The RFC pins it down narrowly: non-existent means NXDOMAIN, the DNS response code for a query for a name that does not exist. If DNS answers with anything else, the name counts as existing, and then np does not apply, sp or p does.
Now DNSSEC enters the picture. Certain DNSSEC signing methods do not return an NXDOMAIN for non-existent names. The method is called Compact Denial of Existence, standardized as RFC 9824 since September 2025, originally introduced by Cloudflare as "black lies" back in 2016. The idea: instead of signing an NXDOMAIN for a non-existent name, which means more compute and larger responses, the server answers with a signed NODATA (response code NOERROR, empty answer section). That is cheaper to produce and reveals less about the zone. RFC 9824 only provides for NXDOMAIN on queries without the DNSSEC flag. Since DNSSEC-aware resolvers always set that flag under RFC 3225, a real resolution chain sees NOERROR throughout.
The consequence for DMARC: a Receiver working strictly by RFC 9989 queries a made-up subdomain, gets NOERROR instead of NXDOMAIN, concludes by the standard's own definition that the name exists, and applies sp or p, not np. Your np=reject never takes effect, even though it sits correctly in the record. No error, no syntax problem, just a silent non-effect.
Who is affected? RFC 9824 itself lists the implementations of the base method in Appendix B: Cloudflare, NS1, Amazon Route53, and the optional online-signing module of Knot DNS. Not niche providers. The standard also has a partial fix, a signal called NXNAME, with which a Compact Denial server can still convey the meaning "this really is NXDOMAIN." But that only helps if the entire resolver chain understands the signal and restores the NXDOMAIN status. According to research by dmarcwise.io (June 2026), the common resolvers, including 8.8.8.8 and 1.1.1.1 as well as the major open-source resolvers, do not do that in practice. So the problem is known and addressed in the standard, but the real resolution chain mostly does not close the gap.
On how widespread DNSSEC is, dmarcwise assumes roughly 8 to 10 percent and relies on a study of the top one million domains from December 2024, in which about 44 percent of the DNSSEC-signed domains used NSEC-based Compact Denial. The figures are a good year and a half old and have probably shifted since, in which direction is open. As a rough order of magnitude they still hold up: not an exotic edge case, but not the norm either.
One more word on provider claims. Whether a DNS provider runs Compact Denial cannot always be read reliably off its marketing. dmarcwise reports, for instance, that Azure DNS states RFC 9824 support but does not actually implement it. In the end the only reliable answer is the test on your own domain.
What you can actually do
If you rely on np, first check whether your zone falls into this category at all. Two conditions have to come together: DNSSEC active and Compact Denial in use.
A quick indicator, not proof: query a name that definitely does not exist under your domain and look at the response code.
dig +dnssec random-definitely-does-not-exist.yourdomain.com AThe header line of the response shows status:. An NXDOMAIN there means np works as intended. A NOERROR with an empty answer section points to Compact Denial, and then np can fail to apply at a strict 9989-Receiver. For a solid verdict it is worth looking at the NSEC records, but for a first orientation the response code is enough.
If you are on Cloudflare, NS1 or Route53 with DNSSEC active, assume you are affected until proven otherwise.
To keep this in perspective: np is not worthless, it is just no guarantee under these conditions. sp and p still apply. The mistake would be to leave sp or p weak in the belief that np already covers the made-up subdomains. Under Compact Denial it just does not do that reliably.
Is your domain caught in exactly this trap?
mailaudit checks whether your zone uses DNSSEC and whether it answers non-existent names with NOERROR instead of NXDOMAIN. If both are true, you know your np runs into nothing at strict Receivers, and where to tighten up with sp and p.
In the next part we get to the enforcement level: p=reject. DMARCbis flips the old recommendation and defines, for the first time in binding language, what full DMARC participation actually means. And what "standard" means in this context, and what it does not.
DMARCbis series
DNS Tree Walk (this post)
p=reject / Full Participation (coming)
NIS2 (coming)
Related posts

NIS2 and DMARC: Why No Law Tells You What to Do
NIS2 never mentions DMARC. For many companies there is still no way around it. The path from the law to the actual technology runs through the state of the art and Germany's BSI technical guidelines. With legal context from Raphael Köllner.

DMARCbis: The tag changes and why t doesn't replace pct
DMARCbis cleans up the DMARC tags: pct, rf, and ri are dropped, while np and t are added. It sounds like routine, but it isn't everywhere. Why t does not replace pct and what this means for the path to full enforcement.

DMARCbis is here. What is changing. And what is not.
The new DMARCbis standard is here: Learn what is changing with email authentication, why your existing record will continue to work, and which DNS details are now important.
