Skip to main content
Reference DMARC RFC 9989

DMARCbis: What Changed in DMARC in 2026 (RFC 9989)

DMARCbis is the 2026 revision of DMARC, published as RFC 9989 (core), RFC 9990 (aggregate reporting), and RFC 9991 (the report schema), replacing the original RFC 7489. It is now a full IETF standard, and it changes four things in the record you publish.

TL;DR

  • 1 The pct tag is gone: receivers ignore it and apply your full policy, so p=quarantine; pct=10 now acts on 100% of failing mail, not 10%.
  • 2 A new t=y test flag stages a policy by applying the next-lower one (p=reject; t=y behaves like quarantine, p=quarantine; t=y like none) while still reporting.
  • 3 A DNS tree walk replaces the Public Suffix List for finding your organizational domain, and a new np tag sets the policy for non-existent subdomains.

Watch

What DMARCbis (RFC 9989) changes in your record: the removed pct, rf, and ri tags, the new t=y test flag, the DNS tree walk, and the np tag for non-existent subdomains.

What it does

DMARC ran on RFC 7489, an Informational document, from 2015. In 2026 the IETF published DMARCbis as Standards-Track: RFC 9989 (the core protocol), RFC 9990 (aggregate reporting), and RFC 9991 (the report schema), obsoleting RFC 7489. The policy model is the same, but several mechanics changed, and most records published before 2026 now contain tags that do nothing or behave differently than their owners expect.

The headline change is that the pct tag was removed. Under the old spec, pct=10 told receivers to apply your policy to roughly 10% of failing mail and the next-lower policy to the rest, which people used to ramp enforcement gradually. DMARCbis receivers ignore pct entirely, so p=quarantine; pct=10 now quarantines everything, not 10%. If you were leaning on a low pct to soften a rollout, you are actually at full enforcement.

To stage a rollout safely, DMARCbis adds the t (testing) tag. t=y tells receivers to apply the next-lower policy and treat the result as a test while still sending reports: p=reject; t=y behaves like quarantine, and p=quarantine; t=y behaves like none. You publish the stricter policy in test mode, watch the reports, then drop t=y to enforce.

How it works

  1. 1

    Removed tags: pct, rf, and ri are no longer part of DMARC, and receivers ignore them. Clean them out of your record so it reflects what actually happens.

  2. 2

    The t=y test flag: publish a stricter policy with t=y to stage it. Receivers apply the next-lower policy (reject becomes quarantine, quarantine becomes none) and keep reporting, so you get a real-traffic rehearsal with no surprise blocking. Drop t=y (or set t=n) to enforce.

  3. 3

    DNS tree walk: to find your organizational domain, receivers now walk up your domain's labels one level at a time looking for a DMARC record, instead of consulting the static Public Suffix List. It is more accurate and removes a brittle external dependency.

  4. 4

    The np tag: np sets the policy for subdomains that do not exist. Attackers spoof made-up subdomains like invoices.yourcompany.com, which the p and sp tags do not cover. np=reject closes that gap in one line.

Example record

_dmarc.yourdomain.com TXT Click to select
v=DMARC1; p=reject; np=reject; rua=mailto:dmarc@yourdomain.com; ruf=mailto:dmarc@yourdomain.com; fo=1

Common pitfalls

  • Keeping a pct tag in your record. It does nothing on a modern receiver and misleads anyone reading the record into thinking enforcement is partial. Remove it.

  • Using t=y on an already-enforcing policy. Because t=y drops you to the next-lower policy, adding it to p=reject downgrades you to quarantine. Use t=y only to stage a step up, then remove it.

  • Leaving out np. Without it, a non-existent subdomain falls back to sp (or p), which many records set loosely, so phantom subdomains stay spoofable. Set np=reject.

  • Assuming nothing changed because your old record still validates. RFC 7489 records are still parsed, but pct, rf, and ri are silently ignored, so the behavior you intended years ago is not the behavior you get in 2026.