DMARC is now an IETF standard, and records written for the old specification can behave differently, or carry tags that no longer do anything, under RFC 9989. Published in May 2026 as a Proposed Standard, RFC 9989 obsoletes RFC 7489 and the experimental RFC 9091, splits reporting into RFC 9990 (aggregate) and RFC 9991 (failure), removes the pct tag, adds np, psd and t, and replaces Public Suffix List lookups with a DNS tree walk. This guide is a change-focused companion: it lists what changed, how each change affects existing records and report tooling, how to audit a domain portfolio, and how to move staged rollouts that relied on pct. It is for email administrators, DNS owners, security teams that run DMARC programmes and providers that process reports. For SPF, DKIM and DMARC fundamentals and a rollout from p=none to p=reject, see the DMARC, SPF and DKIM Guide.
Key takeaways
- pct is gone, so staged percentages stop working. RFC 9989 marks pct as historic and unknown tags are ignored, so a record of p=reject; pct=10 is read by updated receivers as plain p=reject. Use t=y or subdomain-level policies to stage instead.
- np=reject is the quickest win. The new np tag sets policy for subdomains that do not exist in DNS, closing a spoofing route with almost no risk to legitimate mail.
- Organisational domain discovery has changed. The DNS tree walk, capped at eight queries, decides alignment boundaries, and psd=n lets you pin your organisational domain explicitly.
- Reporting is now three documents. RFC 9990 aggregate reports require one policy domain per report, a DKIM selector, a new XML namespace and external destination verification, so report parsers need updating.
- Policy is still a request. RFC 9989 tells receivers not to reject solely on p=reject and advises domains whose users post to mailing lists against publishing p=reject, which affects how far you push enforcement.
What changed: RFC 7489 to RFC 9989
RFC 7489 (2015) was an Informational document published through the Independent Submission stream. RFC 9989 is a Standards Track document from the IETF DMARC working group, published on 19 May 2026. The core mechanism (SPF or DKIM pass plus alignment with the RFC5322.From domain) is unchanged, but discovery, tags and reporting are not.
| Area | RFC 7489 | RFC 9989 and companions | What to do |
|---|---|---|---|
| Status | Informational, Independent Submission | Proposed Standard; obsoletes RFC 7489 and RFC 9091 | Update policies, contracts and audits that cite RFC 7489 |
| Organisational domain | Public Suffix List | DNS tree walk, maximum eight queries | Check deep and multi-tenant domains; consider psd=n |
| pct | Percentage of failing mail to which policy applies | Historic, ignored | Remove; stage with t=y or per-subdomain policy |
| rf, ri | Failure report format, aggregate interval | Historic, ignored | Remove from records |
| np | Not in RFC 7489 (introduced by experimental RFC 9091) | Policy for non-existent subdomains; falls back to sp, then p | Add np=reject |
| psd | Experimental RFC 9091 only | y, n or u (default u) | Registries use psd=y; organisations may use psd=n |
| t | Not present | Test mode, y or n (default n); policy applied one level lower | Use for staged enforcement |
| Aggregate reports | Section 7 and Appendix C of RFC 7489 | RFC 9990, new namespace and clarified schema | Update parsers and report providers |
| Failure reports | Within RFC 7489 | RFC 9991 | Review whether you need them at all |
Tag-by-tag review under RFC 9989
| Tag | Values and default | Behaviour to know | Review action |
|---|---|---|---|
| v | DMARC1, required, first | Case-sensitive | Confirm exact spelling; anything else invalidates the record |
| p | none, quarantine, reject | If absent from an otherwise valid record, treated as p=none | Set explicitly on every organisational domain |
| sp | none, quarantine, reject; falls back to p | Ignored on records published at subdomains of organisational domains and public suffix domains | Set at the organisational domain, not at subdomains |
| np | none, quarantine, reject; falls back to sp, then p | Applies when the subdomain does not exist in DNS | Add np=reject, even while p is still none |
| psd | y, n, u (default u) | Stops the tree walk; psd=n marks the organisational domain | Consider psd=n on your registered domains |
| t | y, n (default n) | With t=y, receivers apply the policy one level lower (reject becomes quarantine); reports are not affected | Replace pct-based staging |
| adkim, aspf | r or s (default r) | Strict requires exact domain match | Keep relaxed unless every sender uses the exact domain |
| rua | Comma-separated URIs | Receivers must support mailto:; external destinations must authorise receipt | Check every destination has its authorisation record |
| ruf, fo | URIs; fo 0, 1, d, s (default 0) | fo is ignored without ruf; 0 and 1 are mutually exclusive | Decide whether failure reports are worth the personal data they carry |
| pct, rf, ri | Historic | Ignored as unknown tags by updated receivers | Remove to avoid misleading anyone reading the record |
Two error rules matter for audits. If multiple DMARC records are returned for one name, all are discarded, so a duplicate TXT record silently disables DMARC. And if a record lacks a valid p (or has an invalid sp or np) but has a valid rua, receivers act as if p=none, which means a typo in the policy downgrades you to monitoring while reports keep arriving and nothing looks broken.
The DNS tree walk and the organisational domain
RFC 7489 depended on the Public Suffix List to find the organisational domain, which sets the boundary for relaxed alignment and the fallback record for subdomains. RFC 9989 replaces that with a walk up the DNS tree.
- Query the author domain: look for a DMARC record at _dmarc.<author domain>.
- Walk up: if none is found, query parent names in turn. Author domains with more than eight labels never cause more than eight queries: when there are eight or more labels, the walk shortens the name to seven labels before continuing.
- Discard invalid records: records without v=DMARC1 are ignored, and multiple records at one name are all discarded.
- Stop on psd: the walk stops at a valid record carrying psd=n or psd=y.
- Select the organisational domain: from longest to shortest name with a record, a record with psd=n makes that domain the organisational domain; a psd=y record found above the starting point makes the name one label below it the organisational domain; otherwise the record with the fewest labels wins.
What this means in practice
- Typical company domains: for example.com with mail from mail.example.com, the result is the same as before: example.com is the organisational domain and relaxed alignment works between them.
- Country-code second levels: for example.co.uk the outcome depends on whether a record exists at co.uk. Public suffix operators that publish DMARC records with psd=y make the boundary explicit.
- Multi-tenant platforms: SaaS providers that give each customer a subdomain (customer.platform.example) must think about whether customers should be treated as separate organisational domains. Publishing records with psd=y at the platform level, or psd=n at each tenant, gives an explicit answer instead of relying on list membership.
- Pinning your boundary: adding psd=n to your organisational domain's record stops the walk there and removes ambiguity if a parent ever publishes a record.
- DNS failures: RFC 9989 leaves DNS error handling to receivers, which may fail open or temporarily reject. Reliable, monitored DNS for _dmarc names matters more now that discovery can take several queries. See the DNS Security Guide.
Replacing pct: staging enforcement under RFC 9989
Under RFC 7489, many programmes moved to enforcement in steps such as p=quarantine; pct=25, and some used pct=0 as a trick to publish quarantine while receivers acted as if p=none. RFC 9989 marks pct as historic, and because unknown tags are ignored, updated receivers will apply the full policy to all failing mail. Mixed receiver populations make the transition worse: some still honour pct, some do not.
| Old record | Intent | RFC 9989 equivalent |
|---|---|---|
| p=quarantine; pct=0 | Signal intent, act as none | p=quarantine; t=y (applied one level lower, as none) |
| p=reject; pct=0 | Signal reject, act as quarantine-lite | p=reject; t=y (applied as quarantine) |
| p=quarantine; pct=25 | Quarantine a quarter of failures | No percentage option: use p=quarantine on selected subdomains first, or p=quarantine; t=y |
| p=reject; pct=50 | Reject half of failures | p=reject; t=y until reports show clean authentication, then remove t |
RFC 9989 section 7.4 suggests a measured path for domains that want p=reject: p=none for at least a month, then p=quarantine for a similar period, comparing disposition results in aggregate reports at each stage. Per-subdomain policies (marketing.example.com at reject while the parent stays at quarantine) are now the main way to enforce for part of your mail.
Reporting changes: RFC 9990 and RFC 9991
- One domain per report: RFC 9990 states that each aggregate report must contain data for only one DMARC policy domain. Parsers that assumed otherwise can mis-attribute data.
- New schema details: the XML namespace urn:ietf:params:xml:ns:dmarc-2.0, a clarified XSD, a more structured report ID, optional namespaced extensions at file and record level, PSD support, and a required DKIM selector element whenever a DKIM signature is reported.
- Frequency and size: reports are daily or more frequent (RFC 9989 says receivers should send aggregate reports at least every 24 hours), should be GZIP-compressed, and should carry no more than 100 DKIM signatures per row.
- External destinations: before sending reports to a domain outside the domain owner's control, receivers check for a TXT record containing v=DMARC1 under the destination's _report._dmarc name; a wildcard record can authorise all domains. If you use a report processing provider, confirm it publishes these records for your domains, or reports quietly stop.
- Failure reports: per-message failure reporting is now RFC 9991. Few large receivers send them, and they can contain message headers and content, so treat ruf destinations as personal data processing. See the DMARC Buyer's Guide when choosing a report processor.
Receiver and mailing list implications
If you run inbound mail, RFC 9989 also affects you as a receiver. It says the receiver can choose to honour the domain owner's request but is not required to do so, and that failed messages are handled under local policy. Section 7.4 goes further for indirect mail: it tells receivers not to reject solely because the sending domain publishes p=reject, and to treat such mail as quarantine where they lack other evidence such as sending patterns and content analysis.
- Domains with p=reject: must not rely on SPF alone and must apply valid DKIM signatures, because forwarding usually breaks SPF while DKIM often survives.
- Domains whose users post to lists: RFC 9989 says they should not publish p=reject, and if they do, should warn users that list participation may be affected. Universities, open source foundations and standards participants are typical cases; consider a separate subdomain for staff who need list participation.
- Mailing list operators: From header rewriting remains the established workaround. RFC 9989 notes ARC has not yet achieved wide adoption.
- Gateway configuration: review whether your secure email gateway hard-rejects on DMARC failure and align it with the RFC guidance and your risk appetite. See the Email Security Buyer's Guide.
How to review your domain portfolio: a phased approach
- Inventory domains: list every registered domain, including parked, legacy and brand domains, plus subdomains that send mail. Parked domains need records too.
- Pull current records: query _dmarc for each and parse tags. Flag duplicates, invalid v or p values, pct, rf and ri, missing np, missing rua and external rua destinations.
- Classify each domain: sending and enforced, sending and monitoring, non-sending, or delegated to a third party (for example a marketing platform subdomain).
- Fix errors first: remove duplicate records and correct syntax, because these silently disable or downgrade DMARC.
- Add np and clean tags: add np=reject on every organisational domain and remove historic tags. For non-sending domains publish v=DMARC1; p=reject; with SPF -all and no DKIM keys.
- Convert pct staging: replace pct-based records with t=y or subdomain policies, using the table above, and record the change date so report trends can be read correctly.
- Update report tooling: confirm your parser or provider handles RFC 9990 reports, the new namespace and one-domain-per-report, and that external destination authorisation records exist.
- Test and roll back: change one low-volume domain first, watch aggregate reports for a week, then apply in batches. Keep old records in version control so a change can be reverted by restoring the previous TXT value; lower TTLs before changes to shorten rollback time.
- Write it into standards: update the email security standard and supplier requirements to cite RFC 9989, RFC 9990 and RFC 9991 instead of RFC 7489.
Decision guidance
- When to use psd=n: worthwhile for organisations with deep subdomain structures or where a parent name could publish DMARC. For a simple example.com it changes little but costs nothing.
- When to keep p=quarantine instead of reject: if many staff post to mailing lists or you depend on forwarding, quarantine plus strong DKIM may be the better long-term state, as RFC 9989 itself suggests.
- When to request failure reports: rarely. Aggregate reports cover most diagnosis, and failure reports bring privacy obligations.
- Small organisations: fix duplicates and syntax, add np=reject, remove pct, and confirm your DMARC report service supports RFC 9990. That is usually an afternoon's work.
- Large organisations and providers: automate record linting in DNS change pipelines, track every domain's state in a register, and treat report processing as a supplier with access to message metadata.
Where identity fits
Every authorised sender is a non-human identity acting for your domain: marketing platforms, ticketing systems, HR tools and cloud services with SPF includes or delegated DKIM keys. RFC 9989 does not change that, but a portfolio review is the right moment to remove senders nobody owns, rotate DKIM keys held by former suppliers and record an owner for each. See the Email Identity and BEC Guide.
Detection and measurement
| Metric | What it shows | Target |
|---|---|---|
| Domains with a single valid DMARC record | No silent failures from duplicates or syntax errors | 100% of registered domains |
| Organisational domains with np=reject | Non-existent subdomain spoofing closed | 100% |
| Records still carrying pct, rf or ri | Migration progress | Zero |
| Share of legitimate mail passing aligned DKIM | Readiness for enforcement and resilience to forwarding | Above 98% for each sending service |
| Domains at p=quarantine or p=reject without t=y | Real enforcement coverage | Rising to all sending domains that can support it |
| Days since last aggregate report per domain | Reporting pipeline health, including external destination authorisation | No more than 2 days |
Also alert on DNS changes to any _dmarc name outside change control, and on new sending sources appearing in aggregate reports.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| CIS Controls v8.1 | Safeguard 9.5 Implement DMARC | Directly requires DMARC policy and verification |
| NIST SP 800-53 Rev. 5 | SI-8 Spam Protection; SC-20 Secure Name/Address Resolution Service (Authoritative Source) | Email protection and integrity of the DNS that publishes policy |
| NIST CSF 2.0 | PR.PS-01 Configuration management; DE.CM-09 Monitoring of software and data | Managing records as configuration; monitoring reports |
| ISO/IEC 27001:2022 | Annex A 5.14 Information transfer; 8.9 Configuration management | Securing email transfer and controlling DNS configuration |
| MITRE ATT&CK v20 | T1566 Phishing | DMARC limits direct-domain spoofing used in phishing |
Common failure patterns
- Assuming pct still throttles enforcement: leaving p=reject; pct=10 in place and finding that updated receivers now reject all failing mail.
- Duplicate records: a second TXT record added by a vendor or migration tool, which causes receivers to discard both.
- Policy typos that downgrade quietly: an invalid p value plus a valid rua, so receivers act as p=none while reports keep flowing.
- Forgotten parked domains: brand and legacy domains with no DMARC record, used for spoofing while the main domain is at reject.
- Broken reporting after a provider change: external rua destinations without the _report._dmarc authorisation record, so data stops and nobody notices.
- Parsers that never learned RFC 9990: tooling that mishandles the new namespace or assumes several domains per report, producing wrong pass rates.
Practitioner checklist
- Inventory all registered and sending domains and pull every _dmarc record.
- Remove duplicate records and fix any invalid v, p, sp or np value.
- Add np=reject to every organisational domain.
- Remove pct, rf and ri, and convert pct-based staging to t=y or subdomain policies.
- Decide on psd=n for organisational domains with deep or shared structures.
- Confirm report processors support RFC 9990 and publish external destination authorisation records.
- Ensure every domain at p=reject DKIM-signs all legitimate mail and does not rely on SPF alone.
- Review inbound gateway behaviour on DMARC failure against RFC 9989 section 7.4.
- Update internal standards and supplier requirements to cite RFC 9989, 9990 and 9991.
Standards and references
- IETF: RFC 9989, Domain-Based Message Authentication, Reporting, and Conformance (DMARC)
- IETF: RFC 9990, DMARC Aggregate Reporting
- RFC Editor: RFC 9989 information page (status, obsoletes, related RFCs)
- RFC Editor: RFC 9991, DMARC Failure Reporting
- RFC Editor: RFC 7489, Domain-based Message Authentication, Reporting, and Conformance (obsoleted)
- MITRE ATT&CK: Phishing (T1566)
Related NHI Mgmt Group resources: DMARC, SPF and DKIM Guide · DMARC Buyer's Guide · Email Identity and BEC Guide · DNS Security Guide