← Blog
Dark developer workspace at night with a monitor showing a grid of green DNS record tiles and a handful of amber tiles scattered among them

By DMARCdrift Team

DMARCbis Readiness: How Many Domains Still Publish pct, rf, and ri?

9 min readdmarcresearchrfc

Of the 1,786 unique domains in our September scan that publish a DMARC record, 828 (46.4%) still carry at least one tag that RFC 9989 removed: pct, rf, or ri. That sounds bad, but almost none of it matters. 653 of the 660 records with pct say pct=100, which never changed anything, and rf and ri were never acted on in a way you would notice. Only 7 domains (0.4%) have the setup that actually behaves differently under DMARCbis: an enforcing policy with pct below 100 and no t tag.

The new tags have barely been adopted. One domain publishes t (and it's t=n, the default), 3 publish psd, and 5 publish np.

What changed in RFC 9989

RFC 9989 was published in May 2026. It obsoletes RFC 7489 and RFC 9091, and it is Standards Track, where 7489 was Informational. For the full list of changes, see what changed in RFC 9989. Two changes matter for this scan:

  • pct, rf, and ri are removed. They are gone from the tag list in §4.7, and their IANA registry status is "historic" (§9.3). v=DMARC1 is unchanged, and sp, np, fo, rua, and ruf all remain.
  • t is new. t=y asks receivers to apply your policy one level softer: reject is treated as quarantine, and quarantine as none. It has no effect at p=none (§4.7).

Appendix A.6 explains why pct went away: in practice it was only reliable at 0 or 100. The RFC describes t=y and t=n as "meant to be analogous" to pct=0 and pct=100. It does not say a receiver should read pct=0 as t=y.

Methodology

  • Dataset: the DMARCdrift adoption scan of 2,240 domains across 10 categories, run on September 1, 2026. The domain-level data is on the DMARC adoption research page.
  • Duplicates: 75 domains appear in more than one category (amazon.com is in both the Fortune 100 and the Tranco Top 500), so the scan covers 2,160 unique domains. The overall numbers in this post count each domain once. The sector table counts a domain in every category it belongs to, because each category is read on its own.
  • Denominator: 1,786 unique domains whose DMARC lookup returned a record starting with v=DMARC1. No lookup returned a record that failed this check.
  • Tag detection: we parsed each raw TXT record and checked which tags are present. We did not use the scanner's parsed pct field, because it reports 100 when the tag is missing.
  • Script: scripts/dmarc-adoption/dmarcbis-readiness.py in our repo. Every number below is copied from its output.

The removed tags: 828 of 1,786

Tag Domains Share of DMARC publishers
Any of the three 828 46.4%
pct (any value) 660 37.0%
pct=100 653 36.6%
pct below 100 7 0.4%
rf 92 5.2%
ri 452 25.3%

pct=100 is a no-op. It was the default in RFC 7489, so writing it out never changed anything. Under DMARCbis the tag is ignored, which leaves you with the same full policy you already had. It's leftover config: delete it the next time you edit the record.

rf and ri are ignored. rf picked a failure-report format, and RFC 7489 §6.3 defined only one value for it (afrf). ri requested a reporting interval, but the same section only required receivers to support daily reports and treated anything else as best effort. Dropping them changes nothing you would see.

The one case that matters: 7 domains

Under RFC 7489, p=reject; pct=50 asked receivers to reject half of failing mail and quarantine the rest (RFC 7489 §6.6.4). Under p=quarantine; pct=0, failing mail got normal handling.

A DMARCbis receiver ignores pct, so it only sees p=reject or p=quarantine and applies the full policy request. The record you published as a partial rollout becomes full enforcement. The receiver still makes the final handling decision (§5.4, §7.4), but the request it acts on is no longer the one you meant.

7 of 1,786 DMARC publishers (0.4%) are in this position: p=quarantine or p=reject, pct below 100, and no t tag. Six are at p=quarantine and one is at p=reject. One uses pct=0 and six use a value from 1 to 99. That is a small number. Most organizations that used pct for a staged rollout either finished it or never started one.

As of the September 1 scan, the seven were:

Domain Category Policy pct
marathonpetroleum.com Fortune 100 p=quarantine 50
qualys.com Cybersecurity Vendors, Top 100 SaaS p=reject 50
illinois.gov State Governments p=quarantine 75
rubiconproject.com Tranco Top 500 p=quarantine 50
samsungcloud.com Tranco Top 500 p=quarantine 50
vungle.com Tranco Top 500 p=quarantine 5
shopifysvc.com Tranco Top 500 p=quarantine 0

None of these is a misconfiguration under the rules they were written for. They are staged rollouts whose meaning shifts as receivers move to DMARCbis. The biggest shift is p=quarantine; pct=0: a record that asked for no quarantine at all becomes a full quarantine request.

If you're using pct below 100 to stage a rollout, there are two fixes:

  • Keep the rollout soft for both generations. Publish t=y; pct=0 together. RFC 7489 receivers ignore the unknown t tag and honor pct=0. DMARCbis receivers ignore pct and honor t=y. See the pct deprecation post for the staged approach.
  • Or finish the rollout. If your aggregate reports show clean alignment, remove pct and enforce fully.

The new tags: 1 t, 3 psd, 5 np

t: one domain publishes it, ironscales.com, with t=n. That is the default, so it asks for exactly what the record would do without it. No domain in the scan publishes t=y.

psd: three domains publish it, and they show both intended uses. myshopify.com publishes psd=y, which is what a public suffix operator is supposed to do: myshopify.com is on the Public Suffix List, since every shop gets its own subdomain. berkeley.edu and arxiv.org publish psd=n. RFC 9989 §4.7 says that value means the record "is published for a domain that is not a PSD, but it is the Organizational Domain for itself and its subdomains."

np: five domains publish it, all as np=reject. np sets the policy for subdomains that don't exist. It started in RFC 9091, an experimental extension, and is now part of the core spec. Because it existed before DMARCbis, it's the one newly standard tag that some domains already use.

Policy distribution, for context

Policy Domains Share
p=reject 1,470 82.3%
p=quarantine 161 9.0%
p=none 151 8.5%
Missing or invalid p 4 0.2%

Federal .gov domains make up 1,111 of the scan's 1,865 DMARC entries, and 93.4% of them are at p=reject, which pulls the overall shares up. See the September adoption update for the per-category policy picture.

By sector

This table counts domain entries, so a domain in two categories appears in both rows. Some sectors have only 25 to 50 domains with DMARC, where one domain moves the share by 2 to 4 points. Read the raw counts, not only the percentages.

Sector With DMARC Any removed tag pct=100 pct below 100 t psd np
US Federal .gov 1,111 564 (50.8%) 436 0 0 0 2
Tranco Top 500 342 140 (40.9%) 126 4 0 2 2
Top 100 SaaS 100 49 (49.0%) 42 1 0 0 0
Fortune 100 99 38 (38.4%) 24 1 0 0 0
Top 50 Universities 50 15 (30.0%) 14 0 0 1 1
State Governments 44 16 (36.4%) 8 1 0 0 0
Cybersecurity Vendors 40 14 (35.0%) 11 1 1 0 0
Major News Outlets 29 14 (48.3%) 14 0 0 0 0
Top 25 US Banks 25 7 (28.0%) 2 0 0 0 0
Hospital Systems 25 4 (16.0%) 4 0 0 0 0

Every pct below 100 in the scan sits on an enforcing policy, so the "pct below 100" column is also the risky count for each sector. Federal .gov has the highest share of leftover tags (half its records carry one) and none of the risky ones: its pct values are all 100.

Cleanup checklist

  1. Look up your record. Run dig TXT _dmarc.yourdomain.com +short, or use the DMARC checker, which explains each tag in your record.
  2. pct=100: delete it. Nothing changes.
  3. rf= or ri=: delete them. Nothing changes.
  4. pct below 100 with p=quarantine or p=reject: decide now. If you're still testing, publish t=y; pct=0 together. If you're done testing, remove pct.
  5. pct with p=none: delete it. It had no effect at p=none.
  6. Leave v=DMARC1 alone. There is no DMARC2 version string.
  7. Keep rua. Aggregate reports are how you find out whether the change broke anything. DMARCdrift reads them for you, along with any failure reports you receive, and alerts you when your published policy changes.

Check your DMARC record now to see which of these apply to you.