Which RFCs to cite now, and the old record vs the new one
The 2015 document, RFC 7489, was Informational and carried DMARC, aggregate reporting and failure reporting in one place. The 2026 replacement splits that into three Standards Track documents: RFC 9989 for the DMARC protocol and record, RFC 9990 for aggregate (rua) reporting, and RFC 9991 for failure (ruf) reporting. When you write a runbook or a ticket, cite the specific RFC and year, because a checker or a colleague working from a pre-2026 article will reach different conclusions about the same record.
Most of the practical changes are things you can see in a published record: a tag that no longer does anything, a size suffix that validators now flag, or a policy that resolves differently because discovery rules changed. The table below is the quick reference; the sections after it link each change to the field note that works through it.
| Element | Legacy — RFC 7489 (2015) | Current — RFC 9989 / 9990 / 9991 (2026) |
|---|---|---|
| Spec maturity | Informational | Standards Track |
| Organizational Domain | Resolved via the Public Suffix List | DNS tree walk, climbing labels up from the From domain |
| pct= tag | Partial-rollout percentage | Removed; stage with the testing flag plus report evidence |
| Subdomain policy | sp= only | sp= for existing subdomains, np= for non-existent ones |
| ri= interval | Requested aggregate-report interval | Historic; receivers control report cadence |
| rua size suffix (e.g. !10m) | Advisory maximum report size | Removed; packaging handled by RFC 9990 |
| Aggregate reporting spec | Inside RFC 7489 | Split out to RFC 9990 |
| Failure reporting spec | Inside RFC 7489 | Split out to RFC 9991 |
Policy discovery: the DNS tree walk replaced the Public Suffix List
Under the old model a receiver used the Public Suffix List to decide where your Organizational Domain boundary was, then looked for a DMARC record there. The 2026 spec removes that dependency. A receiver now performs a DNS tree walk: it queries _dmarc at the exact From domain, and if there is no record it climbs one label at a time, up to a bounded number of steps, until it finds one or runs out of labels.
The practical effect is that a stale public-suffix entry and a current tree-walk implementation can disagree about which policy applies to a multi-label domain, and that disagreement looks mysterious because both tools show valid DNS. Publish an explicit record at the domain you actually want to govern, and log each _dmarc query and the stopping point when you debug.
pct is gone: stage enforcement on evidence, not a percentage
The pct tag let a domain apply its policy to only a fraction of failing mail. Receivers implemented it inconsistently, so the current spec removed it. Records copied from old tutorials often still carry something like p=quarantine; pct=10, and some validators render that as syntactically fine even though the percentage no longer means anything.
Staged rollout now works differently: publish p=none first and use the aggregate reports as a sender inventory until every legitimate stream aligns, then move to quarantine and reject. A testing flag exists for cautiously trialling an enforcing policy, but it is a switch, not a dial. The goal is an evidence-based enforcement plan, not an imagined ramp.
sp and np: existing subdomains vs non-existent ones
The current spec makes the subdomain story explicit with two tags. sp sets policy for subdomains that exist in DNS and inherit from the parent. np sets policy for names that do not exist at all, which is the case an attacker exploits by inventing random.example.com to send lookalike mail. When both tags are absent, fallback rules eventually apply the parent p policy.
Model your DNS tree before choosing values. A dedicated sending subdomain can publish its own record; everything else should be covered by the Organizational Domain record so the tree walk finds one policy for every child. Subdomain policy is not a substitute for getting alignment right on the mail you actually send.
Reporting moved out: ri is historic, size suffixes are gone
Aggregate reporting is now its own document, RFC 9990, and two record habits did not survive the move. The ri tag, which asked for a specific report interval, is historic: receivers decide cadence, typically one file per day, and a monitor that expects hourly XML because a record says ri=3600 will wrongly conclude reporting is broken. The report-URI size suffix, written as something like !10m, has also been removed; a current validator flags it, and report packaging is handled by the spec rather than by the domain owner.
Update ingestion accordingly: drop ri from templates, widen the alert window that flags a receiver as silent, key every record to the begin and end timestamps inside the report rather than to when the file landed, and grep DNS and infrastructure-as-code for any leftover size notation on a rua address.
External reporting still needs an authorization record
If your rua or ruf address is on a different domain from the one being protected — a monitoring service, or a separate reporting subdomain — the destination has to publish a record authorizing it to receive those reports. This has not changed in spirit, but it is still the most common reason reports arrive from some receivers and not others, which makes external reporting look randomly unreliable.
When reports are missing, check the external-destination authorization record in DNS before looking at the mailbox or the parser, expect genuine receiver-to-receiver variation, and protect that authorization record during any later DNS cleanup.
The DKIM and unsubscribe RFCs that pair with this
Two adjacent standards come up in the same audits. RFC 8301 sets DKIM's cryptographic floor: use rsa-sha256, keep RSA keys at or above 1024 bits, and prefer 2048 where the provider and DNS path allow — and remember that key length lives in the key pair at the signer, not in the DNS TXT string alone. RFC 8058 defines one-click unsubscribe, and its easily missed requirement is that a valid DKIM signature must cover the List-Unsubscribe and List-Unsubscribe-Post headers, not merely that those headers are present in the delivered message.
Both are worth checking whenever you touch DMARC, because a migration that changes signing or gateway behaviour can quietly break either one while the DMARC record itself still looks correct.
Common questions
Is RFC 7489 still the DMARC standard?
No. In 2026 the IETF published RFC 9989 for DMARC, RFC 9990 for aggregate reporting and RFC 9991 for failure reporting, replacing the 2015 Informational RFC 7489. Older records mostly still work, but tutorials written against RFC 7489 teach tags and discovery rules that have changed.
Does the pct tag still work in 2026?
The pct tag was removed because receivers applied it inconsistently. Some validators still show a record containing pct as syntactically valid, but the percentage no longer changes how failing mail is handled. Stage enforcement by starting at p=none, resolving every legitimate stream from the aggregate reports, then moving to quarantine and reject.
What replaced the Public Suffix List in DMARC policy discovery?
A DNS tree walk. A receiver queries _dmarc at the exact From domain, and if there is no record it climbs one label at a time, up to a bounded number of steps, until it finds a record or reaches the top. This removes the dependency on a maintained public-suffix list.
Do I need to republish my DMARC record for RFC 9989?
Not usually just to be compliant, but it is worth an audit. Remove pct and any ri tag or rua size suffix, decide sp and np deliberately, and make sure a record exists at the domain the tree walk should find for every subdomain you send from. Also confirm any external reporting destination still authorizes your domain.
What is the difference between the sp and np tags?
sp sets the policy for subdomains that exist in DNS and inherit from the parent domain. np sets the policy for subdomains that do not exist at all, which is the case attackers use when they invent a lookalike author domain. If both are omitted, fallback rules eventually apply the parent p policy.
Are DMARC aggregate reports sent hourly?
No. Cadence is controlled by the receiver, and one file per UTC day is common. The ri tag that used to request an interval is historic in the current spec. Build report ingestion around receiver-controlled daily or more frequent batches, and aggregate by each report's own begin and end times rather than by when the file arrived.