DMARCify logoDMARCify
Standards

DMARC is now an IETF Proposed Standard: what changed in RFC 9989, 9990, and 9991

In May 2026, DMARC moved from RFC 7489 to three Proposed Standard RFCs. Here's what changed in policy records, DNS discovery, aggregate reports, and failure reports. · 7 min read · by DMARCify team

Editorial illustration of RFC 9989, RFC 9990, and RFC 9991 documents next to a DMARC policy panel.
Field note

The record still says DMARC1, but the standard around it is cleaner: no pct rollout tag, DNS Tree Walk replaces PSL discovery, PSD support is explicit, and reports carry more policy context.

In May 2026, DMARC stopped being just the 2015 experimental-looking thing everyone deployed anyway. The IETF published three new RFCs and moved DMARC to Proposed Standard: RFC 9989 for the core protocol, RFC 9990 for aggregate reporting, and RFC 9991 for failure reporting.

This is not a DMARC2 launch. Existing records still start with v=DMARC1, and existing deployments do not need to rename anything. The change is mostly about cleaning up the spec around the operational reality the ecosystem has been living with for years.

The three new documents

  • RFC 9989 is the main DMARC specification. It replaces RFC 7489, updates the policy record tags, defines DNS Tree Walk discovery, and adds clearer conformance language.
  • RFC 9990 covers aggregate reports. It keeps the familiar XML report model, but aligns the schema with the updated policy tags and real-world report behavior.
  • RFC 9991 covers failure reports. Those are per-message forensic reports sent via ruf=, with stronger privacy discussion and mostly incremental behavior changes.

Policy tags changed

The record is still a TXT record under _dmarc. The most visible change is that some older policy tags are gone from the current standard, and a few new ones exist.

Policy record changes
  • Removed: pct, rf, and ri.
  • Added: np for non-existent subdomains.
  • Added: psd for Public Suffix Domain participation.
  • Added: t for testing mode.
  • Unchanged: v=DMARC1 remains the version string.

The practical one is pct=. The old gradual rollout pattern was p=quarantine; pct=10, then increasing the percentage. Under the new specification, DMARCify no longer publishes that tag and no longer recommends percentage ramping. The operational path is simpler: monitor, quarantine, then reject.

DNS Tree Walk replaces PSL discovery

RFC 7489 relied on the Public Suffix List to decide the organisational domain. RFC 9989 replaces that with DNS Tree Walk. A receiver looking at news.mail.example.co.uk can walk up the tree:

_dmarc.news.mail.example.co.uk
_dmarc.mail.example.co.uk
_dmarc.example.co.uk
_dmarc.co.uk
_dmarc.uk

The first valid applicable record wins. That sounds small, but it matters for public suffix domains and for receivers that should not need to ship the same external suffix database to agree on policy discovery.

PSD support is now first-class

Public Suffix Domains could not fully participate in the old model. The new psd= tag and Tree Walk algorithm make that participation explicit. Most ordinary company domains should not publish psd=. It is primarily for suffix operators and special boundary cases.

Aggregate reports now carry more policy context

Aggregate reports are still the daily XML summaries DMARCify ingests. RFC 9990 updates the schema so receivers can report more of the policy they evaluated: sp, np, testing, and discovery_method.

<policy_published>
  <domain>example.com</domain>
  <p>quarantine</p>
  <sp>none</sp>
  <np>reject</np>
  <testing>n</testing>
  <discovery_method>treewalk</discovery_method>
</policy_published>

DMARCify now stores those fields when receivers send them. Legacy reports with pct still parse; new reports without it default internally to full policy application.

Failure reports are still uncommon, but useful to sample

Failure reports are not aggregate XML. They are per-message forensic reports requested with ruf= and controlled by fo=. Many major receivers do not send them, and those that do may redact heavily because message-level reports can contain sensitive data.

DMARCify now publishes a separate f- mailbox for failure reports and stores those messages raw. We are not parsing them yet; the point is to collect real-world samples first, then build the parser against actual receiver behavior.

What changed in DMARCify

  • Generated records now omit pct=.
  • Promotion guidance moved to p=nonep=quarantine p=reject.
  • Live DMARC checks use DNS Tree Walk discovery.
  • Aggregate ingestion stores the new RFC 9990 policy fields.

Backward compatibility

Old records do not stop working because they contain pct=. DMARCify still parses legacy tags and old aggregate reports. The change is in what we publish and what we recommend going forward.

If you already have a working record, there is no emergency migration. If DMARCify manages the record for you, future writes will use the updated form.

DMARC, decoded.

The dashboard surfaces the things this post talks about — alignment, forwarders, source attribution — for every domain you monitor.

One DNS record · 60 seconds to set up