Google requires bulk senders, meaning anyone sending more than 5,000 messages a day to personal Gmail accounts, to set up DMARC for the sending domain. Its published sender guidelines then add a line most people skim past: your DMARC enforcement policy can be set to none. Yahoo's sender requirements say the same thing in different words. Bulk senders must publish a valid DMARC policy with at least p=none.
That single sentence explains why so many domains sit where they sit. The mailbox providers asked for a record. A record is what they got.
A policy of p=none asks receiving systems to do nothing differently. The current DMARC specification is blunt about it: discovered policies of p=none must not modify existing mail handling processes. Reports still arrive, which feels like progress, and the dashboard fills with green. But every spoofed message that fails authentication is delivered exactly as it would have been with no DMARC record at all. Detection without enforcement is a smoke alarm wired to a notepad.
The standard changed in 2026, and the old rollout advice went with it
In May 2026 the IETF published RFC 9989, which moves DMARC onto the Standards Track and obsoletes the original RFC 7489. Aggregate reporting split off into its own document, RFC 9990. If your migration plan came from a blog post or a vendor knowledge base article written before that, one of its central instructions no longer describes a real protocol feature.
The casualty is the pct tag. Under RFC 7489, pct was an integer from 0 to 100 with a default of 100, described as the percentage of messages from the domain owner's mail stream to which the DMARC policy is applied. The stated purpose was exactly the staged rollout everyone recommends: publish p=quarantine with pct=10, watch, raise it to 25, then 50, then 100, then repeat the ladder at p=reject.
RFC 9989 removed the tag, and the rationale in its appendix is worth reading closely. Operational experience showed that the pct tag was usually not accurately applied unless the value was either 0 or 100, and the inaccuracies with other values varied widely from one implementation to another.
Read that again, because it is the trap. Publishing pct=25 did not mean a quarter of failing messages were quarantined. It meant something different at every receiver, and at many receivers it meant nothing at all. The default of 100 was easy to implement because it required no special handling. Everything in between was guesswork dressed as a control. Administrators who ran the ladder for months believed they were metering risk. They were mostly changing a string in DNS and watching numbers that moved for unrelated reasons.
The value 0 was the exception, because intermediaries and mailbox providers adopted it as a signal to deviate from normal handling, usually by rewriting the From header field. That behavior turned out to be genuinely useful, so RFC 9989 preserved it under a new name.
The t tag replaces the part of pct that worked
The replacement is the t tag, short for testing, with values of y and n and a default of n. Setting t=y asks the validating receiver not to apply the stated policy, and instead to apply the policy one level below it. If your record says p=quarantine and t=y, failing messages get none. If it says p=reject and t=y, failing messages get quarantine. The tag has no effect when the policy is already none, and it does not change report generation.
This is the most useful tool in the whole migration, because it inverts the risk. You publish the policy you actually intend, collect disposition data at that policy level, and the worst outcome for a message that fails is a junk folder rather than a bounce.
Expect vendor documentation to lag here. Microsoft's DMARC configuration guidance still cites RFC 7489 and still walks readers up a pct ladder of 10, 25, 50, 75, and 100 as the recommended gradual rollout. That advice was reasonable when written and it is not malicious now, but it describes a tag the standard has retired.
Relaxed versus strict alignment, and why relaxed is the sane default
DMARC does not require both SPF and DKIM to pass. A message satisfies the check if at least one supported mechanism produces a pass and produces it on an identifier that is in alignment with the domain in the From header. Alignment is the entire point. SPF authenticates the envelope sender, DKIM authenticates the signing domain, and neither is what a human reads. DMARC's job is to tie one of them to the visible From address.
Two tags control how strictly that tie is checked. Both aspf and adkim default to r, for relaxed. In relaxed mode, the organizational domains of the authenticated identifier and the From domain must match. In strict mode, only an exact match of the fully qualified domain names counts.
Relaxed is the correct default for almost everyone because real mail systems are built out of subdomains. A message From an address at example.com carrying a DKIM signature with d=mail.example.com aligns under relaxed and fails under strict. A bounce address on a subdomain used by your marketing platform aligns under relaxed and fails under strict. Turning on strict alignment is the fastest way to break mail that was working, and it buys nothing against an external attacker who controls no part of your namespace.
There is a real counter-case, and the specification spells it out. If someone can gain control of DNS for a subdomain of your organizational domain, they can publish an SPF record there and send mail with a From address at your organizational domain. Under relaxed alignment, that message passes DMARC, because the authenticated identifier shares an organizational domain with the From domain. Large organizations that delegate DNS subtrees to departments, or that hand subdomains to vendors and forget them, are carrying this exposure. If you cannot vouch for who controls every subdomain, strict alignment becomes a defensible choice, but fix the delegation first.
Forwarding breaks SPF and preserves DKIM
This is the mechanism that decides whether your p=reject transition succeeds or generates a week of help desk tickets.
Consider an alumni forwarder, or a role address like finance at an association that relays to whoever currently holds the job. A message arrives, the forwarder accepts it and re-sends it to the real mailbox. The receiving server at the far end sees a connection from the forwarder's IP address, not from yours. That IP is not in your SPF record, so SPF fails. It will keep failing, forever, and there is nothing you can publish in DNS to fix it, short of listing every forwarder on the internet.
DKIM survives. A plain forward does not alter the message, so the signature still validates and the signing domain is still yours. The specification states this plainly: DKIM signatures will generally remain valid in these relay situations.
Which produces the single most important requirement in the entire migration, and RFC 9989 states it as a MUST. Domains that publish p=reject must not rely solely on SPF to secure a DMARC pass, and must apply valid DKIM signatures to their messages. It is repeated in the conformance section as a condition of full participation.
The practical consequence changes how you read your reports. A stream that passes DMARC only on SPF looks identical to a fully protected stream in a summary view. It is not. It is a stream that will fail the moment anyone forwards it. The number that matters is aligned DKIM pass, not DMARC pass.
Mailing lists break DKIM too, and ARC is only a partial answer
Forwarding preserves DKIM because it does not touch the message. Mailing lists touch the message constantly. They prepend a tag to the subject line, append an unsubscribe footer to the body, strip or reorder headers, and many rewrite the From header outright. DKIM signs a hash of the body and a set of headers, so any of these edits invalidate the signature. Now SPF fails because the list relayed the message, and DKIM fails because the list edited it. There is no aligned identifier left, and the message fails DMARC.
The downstream damage is worse than one lost message. When a receiver honors p=reject and refuses list traffic, the list software sees a bounce. Repeated bounces look like a dead address, so the list automatically unsubscribes your user. The specification describes this cascade directly, and it is why RFC 9989 says domains hosting users who post to internet mailing lists should not publish p=reject, and that domains choosing to do so anyway should tell those users their list participation may be hindered.
ARC, the Authenticated Received Chain, exists to address this. Defined in RFC 8617, it adds three header fields at each hop that record the authentication result on arrival, sign the message as it stood, and seal the previous entries so the chain cannot be edited. A receiver that trusts the chain can see that the message authenticated correctly before the list touched it, and can choose to deliver rather than reject.
Three qualifiers keep ARC from being a solution you can plan around. RFC 8617 is Experimental, published in 2019, and has never advanced to the Standards Track. Honoring a chain is explicitly discretionary: a DMARC processor may, as a matter of local policy, choose to accept the assessments an ARC chain provides. And it only helps if the intermediary seals in the first place. On the receiving side this shows up as configuration, not automation. Microsoft 365 requires administrators to nominate specific trusted ARC sealers before modified messages stop failing DMARC checks. Yahoo lists ARC as a recommendation for forwarders, not a requirement.
So ARC helps when the intermediary seals, the receiver participates, and the receiver trusts that particular sealer. Treat it as a mitigation that reduces breakage, never as a guarantee that list mail will survive p=reject.
sp and np decide what happens to your subdomains
A DMARC record at your organizational domain covers subdomains by default. The p value applies to the domain queried and to its subdomains unless you override it, which two tags let you do.
The sp tag sets policy for existing subdomains of the organizational domain, and applies only to those subdomains, never to the organizational domain itself. The np tag sets policy for non-existent subdomains, meaning names with no DNS presence at all. The inheritance runs in a specific order: if np is absent, the sp value applies to non-existent subdomains if sp is present, and otherwise the p value applies. If sp is absent and np is absent or not applicable, p applies to subdomains.
Two traps live here.
The first is that sp is ignored on records published at subdomains of organizational domains, because of how policy discovery works. Publishing a record with p=none and sp=reject at a subdomain does nothing for the names beneath it. The sp tag is meaningful at the organizational domain and effectively decorative elsewhere.
The second is more common and more damaging. Administrators nervous about a p=reject cutover often publish p=reject with sp=none, reasoning that they will tighten subdomains later. That record announces to every attacker that the parent is defended and every subdomain is open. Spoofing invoices from a plausible name like billing at a subdomain becomes trivially easy, and the aggregate reports for the parent domain will not show it clearly.
The np tag, by contrast, is close to free. No legitimate mail originates from a subdomain that does not exist in DNS, so np=reject carries essentially no delivery risk while closing off a favorite technique. A reasonable record during a cautious transition sets p=quarantine, sp=quarantine, np=reject and an rua address, with the parent policy raised once the data supports it.
The sender you will never see in your reports
Aggregate reports feel comprehensive. They are not, and the specification never claimed they would be. Sending them is a SHOULD, not a MUST. Receivers should generate and send aggregate reports at least daily, and the specification lists the usual reasons they opt out: resource constraints, local policy against sharing data, and user privacy concerns.
Microsoft documents a concrete and very widespread version of this gap. Microsoft 365 sends aggregate reports only when the MX record for the receiving domain points directly to Microsoft 365. If internet mail routes through a third-party security gateway or an appliance before reaching Microsoft 365, including hybrid deployments that deliver on-premises first, aggregate reports are not sent. Microsoft 365 also never sends failure reports, regardless of what ruf address you publish.
Now assemble the failure case. You have an application, perhaps a billing system, a scanner, a monitoring alerter, or an HR portal, that sends only to a handful of business partners. Those partners are mid-sized companies whose mail routes through a filtering gateway before landing in Microsoft 365. That application appears in exactly zero rows of your aggregate reports. Not as a failure. Not at all. Your dashboard reports full alignment, because the only stream that would have failed is invisible to the instrument measuring it.
Reports prove the existence of what they show. They prove nothing about what they omit. The absence of a sender in your reports means one of two things, and you cannot tell which from the reports themselves: either that sender does not exist, or it only mails receivers who never report.
The only way to close that gap is from the other side. Build a sending inventory from what your organization actually runs, not from what the reports revealed. Finance and ERP systems, ticketing and help desk platforms, monitoring and alerting, multifunction printers and scanners, CRM and marketing platforms, and anything a department bought with a credit card. Then reconcile the inventory against the reports and investigate every entry that appears in one and not the other.
A readiness test you can actually run
Before changing the p value, work through these. Each one has a pass or fail answer, which is the point.
- Every stream on your written sending inventory appears in aggregate reports with an aligned DKIM pass, not merely a DMARC pass. Sort your report data by DKIM-aligned result and treat SPF-only passes as unfinished work.
- Every inventory entry that does not appear in reports at all has been explained, either as decommissioned or as a stream whose receivers do not report. Unexplained absences are blockers.
- A live forwarding test passes. Send from each significant stream to an address that forwards to a mailbox you control, then read the Authentication-Results header at the final destination and confirm a DKIM pass on a signing domain aligned to your From domain.
- You have run the target policy with t=y for a full business cycle, including month-end and any quarterly batch runs, and reviewed the disposition data it produced.
- You have compared disposition counts between a p=none period of at least a month and a p=quarantine period of comparable length, which is the comparison RFC 9989 itself recommends.
- Subdomains are enumerated, sp is set deliberately rather than by accident, np=reject is published, and no subdomain DNS is delegated to a party you cannot vouch for.
Expect this to take months rather than weeks. RFC 9989 says as much, noting that depending on sending cadence it may take many months of consuming aggregate reports before a domain owner is confident all of its mail authenticates properly. It also states that legitimate streams found to be unaligned or unauthenticated must be remediated before any attempt to publish an enforcement policy.
What receivers do with your policy is still their decision
One last piece of realism, and it cuts both ways. RFC 9989 instructs receivers that they must not reject messages solely on the basis of a p=reject policy, and that absent other knowledge and analysis they must treat such failing mail as though the policy were quarantine. Microsoft's implementation reflects this, gating DMARC policy enforcement behind an anti-phishing policy setting rather than applying it unconditionally.
That softens the blast radius of a premature cutover, and it should not comfort you much. The specification concedes in the same section that in practice few receivers apply any mitigation to indirect mail flows, and that mail forwarded through mailing lists with unmodified From headers is frequently rejected outright under p=reject. Some receivers will be gentle. Others will bounce your invoices. You do not get to know which in advance, which is precisely why the readiness work happens before the DNS change and not after the first complaint.
The domains that come through this cleanly are rarely the ones with simple mail. They are the ones that stopped treating the aggregate report as an inventory. A report is a record of what some receivers chose to tell you about traffic they happened to see. The inventory is a list of every system in your organization capable of putting your domain in a From header. The distance between those two documents is the entire risk of moving to p=reject, and it is measured in systems nobody remembered to mention.
