Skip to content
All field notes

DMARCbis (RFC 9989): What Changed in DMARC

RFC 9989 replaced the original DMARC specification in May 2026. The pct, rf and ri tags are gone, t= and np= are standard, and the Public Suffix List is out.

PlatOps Security TeamEmail security4 min read
The short version
DMARC is now a Proposed Standard. RFC 9989 (core), RFC 9990 (aggregate reports) and RFC 9991 (failure reports) were published in May 2026 and obsolete RFC 7489.
Three tags are removed: pct, rf and ri. A record that still carries them keeps working, because receivers ignore tags they do not recognize, but pct= no longer does what it used to.
Two tags matter for most domains: t=y is the new test mode that replaces the pct= ramp, and np= sets a policy for subdomains that do not exist.
Receivers now find your organizational domain by walking up the DNS tree instead of consulting the Public Suffix List.

What was published

In May 2026 the IETF published the revised DMARC specification as three documents:

Together they obsolete RFC 7489, the informational document most DMARC guidance, including ours, was written against. The version tag does not change: records still begin with v=DMARC1.

Tags that were removed

RFC 9989 lists three removed tags in Appendix C.5:

  • pct= asked receivers to apply the policy to a percentage of failing mail. The RFC explains in Appendix A.6 that values other than 0 and 100 were applied inconsistently, and that pct=0 had taken on an unintended meaning for some intermediaries.
  • rf= requested a failure-report format. RFC 7489 defined only one, afrf.
  • ri= requested a reporting interval. Providers kept their own schedule, almost always daily.

A record that still contains these tags is not invalid. Receivers ignore tags they do not recognize. The practical problem is pct=: a rollout plan that depends on pct=25 meaning "a quarter of failing mail" cannot rely on it.

Tags that were added

  • t=, test mode (section 4.7). The default is n. With t=y, receivers apply one level below the published policy: p=quarantine; t=y is handled as none, and p=reject; t=y as quarantine. The same step down applies to sp= and np=. Reports are generated as normal, so test mode shows what the stricter policy would catch.
  • np=, the policy for subdomains that do not exist. It first appeared in the experimental RFC 9091 (2021) and is now part of the standard. If np= is absent, those names fall back to sp=, then p=. Attackers often invent names such as billing.yourdomain.com; np=reject covers them without touching the subdomains you actually use.
  • psd= lets the operator of a public suffix, such as a registry, mark its domain. Customer domains do not need it.

The Public Suffix List is out

To decide which domain's policy applies, receivers used to look up the organizational domain in the Public Suffix List. RFC 9989 replaces that with a DNS tree walk (section 4.10): the receiver queries _dmarc records from the author domain upward, label by label, with the number of queries capped at eight. For a typical domain the result is the same. For organizations with deep or delegated subdomain structures, the record that applies is now decided by what is published in DNS rather than by an external list.

p=reject and mailing lists

Section 7.4 addresses indirect mail flows directly. Domains that publish p=reject must not rely on SPF alone and must DKIM-sign their mail, because forwarding breaks SPF. The RFC also advises that domains whose users post to Internet mailing lists should not publish p=reject. Domains that do move to reject are advised to spend at least a month at p=none, then as long at p=quarantine, and to compare the results first.

For a domain that sends only transactional and marketing mail, p=reject remains the goal. For a domain where people post to lists, read your aggregate reports for list traffic before you decide.

What to change in your record

A common RFC 7489 record during rollout:

v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc@yourdomain.com; ri=86400

The RFC 9989 equivalent:

v=DMARC1; p=quarantine; t=y; np=reject; rua=mailto:dmarc@yourdomain.com

And at enforcement:

v=DMARC1; p=reject; np=reject; rua=mailto:dmarc@yourdomain.com
  1. Remove pct=, rf= and ri=.
  2. Use t=y while you test a new policy, and remove it when the reports are clean.
  3. Add np=reject, which is safe at any stage. While t=y is present, receivers apply it one level lower, as quarantine.
  4. Confirm every sender is DKIM-signed and aligned before p=reject.

The DMARC record generator builds RFC 9989 records, and the DMARC checker flags removed tags in a published record. The rollout playbook walks through each stage with test mode.

Questions we get asked

No record breaks. Receivers ignore unknown or removed tags, so v=DMARC1; p=reject; rua=... is valid under both specifications. Remove pct=, rf= and ri= when you next edit the record, and consider adding np=reject.

Field notes, twice a month.

When a mailbox provider changes the rules, you hear it here with the record you need to change. No digest, no roundup, no product news.

DMARC field notes, twice a month, from PlatOps Security, LLC (Bethesda, MD). We use your address only to send it. Unsubscribe with one click in any issue. Privacy policy.