DMARC explained — without the acronym soup
DMARC became an IETF standard in May 2026 and the Public Suffix List is gone. What changed, and how to read an aggregate report field by field.
DMARC gives a receiving mail server one instruction: when a message claims to come from your domain but neither SPF nor DKIM proves it for that domain, do this. The three permitted answers are do nothing, file it as spam, or reject it. The second half of the protocol matters more in practice — DMARC also asks receivers to post back daily XML reports naming every IP address sending mail as your domain and whether it passed. In May 2026 the IETF republished the whole protocol as RFC 9989, promoting it from Informational to Standards Track and removing the Public Suffix List from its design.
What DMARC instructs a receiving server to do, precisely
The policy lives in a DNS TXT record at the name _dmarc prepended to your domain. dig TXT _dmarc.yourdomain.com +short returns it, and a minimal one looks like v=DMARC1; p=none; rua=mailto:[email protected].
The order of operations matters and is often described backwards. DMARC does not authenticate anything. By the time it runs, SPF has already evaluated the connecting IP against the domain in the envelope return path, and DKIM has already verified any cryptographic signatures on the message. DMARC reads those two results and asks a third question: did either of them pass for the domain in the visible From header? If yes, the message passes DMARC. If no, the published policy applies.
The three dispositions:
p=none— apply no special handling, but send reports. This is an instrument, not a defence.p=quarantine— treat failing mail as suspicious, which in practice means the spam folder.p=reject— refuse failing mail outright. Exchange Online's rejection reads550 5.7.509: Access denied, sending domain contoso.com does not pass DMARC verification and has a DMARC policy of reject, which is the clearest confirmation you will get that a policy is being enforced.
Every one of these is a request. A receiver is free to ignore it, and some do for particular sources. DMARC is a published preference plus a feedback channel, not an access control list.
Alignment is the whole idea, and it is where working setups break
Alignment is the requirement that a check authenticated the same domain a human sees. Three domains are in play in every message, and people conflate them constantly:
- The envelope return path — the
MAIL FROMaddress, which is what SPF evaluates. It is invisible in a normal mail client and frequently belongs to your sending platform rather than to you. - The DKIM signing domain — the
d=value inside theDKIM-Signatureheader. Also invisible, also frequently the platform's. - The From header domain — the one the recipient reads, and the only one DMARC cares about protecting.
Two modes control how strictly the comparison is made, and RFC 9989 defines both as defaulting to relaxed. adkim "indicates whether the Domain Owner or PSO requires strict or relaxed DKIM Identifier Alignment mode", with default r; aspf does the same for SPF, also defaulting to r. Relaxed means the organisational domains must match, so mail.example.com aligns with example.com. Strict, written adkim=s or aspf=s, requires an exact match.
The single most common failure in cold outreach follows directly. Your Authentication-Results header shows spf=pass and dmarc=fail. Nothing is broken in your SPF record. SPF passed for your sending platform's return-path domain, which authenticates something true about the platform and nothing at all about you. The fix is a DKIM signature with d= set to your own domain, or a custom return path that puts your domain in the envelope — not another include: in your SPF record. What each of the three protocols actually authenticates is worth being precise about before touching any record.
What changed in May 2026, and why it is more than housekeeping
RFC 7489, the DMARC specification everyone built against from 2015, was an Informational RFC. It described a protocol already in deployment rather than standardising one. In May 2026 the IETF published a replacement set:
- RFC 9989, "Domain-Based Message Authentication, Reporting, and Conformance (DMARC)" — the core protocol, Standards Track, obsoleting RFC 7489 and RFC 9091.
- RFC 9990 — aggregate reporting, previously an appendix.
- RFC 9991 — failure reporting.
Appendix C of RFC 9989 lists the substantive changes. The pct tag was removed. Two new policy tags arrived: np, the "Domain Owner Assessment Policy for non-existent subdomains", and t for test mode. A psd tag flags a public suffix domain, with values y, n or u. And the Public Suffix List was replaced with "a discovery technique known colloquially as the 'DNS Tree Walk'".
Records published under the old specification keep working. What changes is what you should build and what you should stop assuming.
The tree walk that replaced the Public Suffix List
DMARC has always needed the concept of an organisational domain — the registrable domain that subdomains inherit policy from. Under RFC 7489, finding it meant consulting the Public Suffix List, a community-maintained text file enumerating every suffix under which the public can register names. That is an odd dependency for a mail protocol: a file, updated on somebody else's schedule, that every implementation had to ship a copy of and keep current.
RFC 9989 replaces it with a DNS query sequence. The receiver walks up the label chain from the From domain, querying for a DMARC record at each level, and the first record it finds governs. Two practical consequences:
Where you publish now determines what you cover. Publishing a record at an intermediate level changes which policy applies to everything beneath it, immediately, without waiting for a text file to be updated. This gives, in the RFC's own words, "more flexibility to Domain Owners".
A stray _dmarc record is now more dangerous. A forgotten test record at a subdomain will be found by the walk before the parent's record and will govern that branch. Audit the whole tree, not just the apex, whenever behaviour surprises you.
The tags people get wrong
Six worth knowing beyond p:
sp— the policy for subdomains. Absent, subdomains inheritp. Present, it overrides. This is how you enforcep=rejecton your main domain while a legacy system on a subdomain is still being fixed.np— new in RFC 9989, the policy for non-existent subdomains. Attackers commonly spoof names that were never registered, and this closes that specific gap without loosening anything else.rua— where aggregate reports go, as one or moremailto:URIs. This is the tag that does the work.ruf— where failure reports go. These contain message content or headers, which is a privacy exposure, and many large receivers decline to send them at all. Setting it is usually not worth the mailbox it fills.ri— requested reporting interval in seconds. RFC 9990 notes that "typically, the reporting period will encompass a single UTC day, beginning at 0000UTC", so asking for something more granular is a request most receivers will not honour.pct— removed. If you have it, plan to drop it rather than depend on it.
The SPF, DKIM and DMARC record generator produces a record with these tags set consistently, and the record checker reads back what is actually resolving, which is not always the same thing as what you published.
How to read an aggregate report, element by element
An aggregate report arrives as a compressed XML file attached to an email, and the filename itself is structured. RFC 9990 specifies the convention as the receiver's name, the policy domain, the beginning timestamp, the ending timestamp and an optional unique id, separated by exclamation marks — the RFC's own example is mail.receiver.example!example.com!1013662812!1013749130.xml.gz. The timestamps are Unix epoch seconds, which is how you tell at a glance whether a report covers the day you care about without opening it.
Inside, four things matter.
report_metadata names the reporting organisation, a contact address, a report id and the date range. Use it to know who is talking and about when.
policy_published is the receiver echoing back the policy it discovered for your domain, including adkim, aspf, p and sp. Read this first on every new report. If it does not match what you believe you published, the rest of the report is describing a different configuration from the one in your head — the record is cached, or truncated, or there are two of them.
record blocks repeat, one per distinct combination of source and result. Each contains a row with source_ip, a count of messages, and a policy_evaluated block giving the disposition applied and the dkim and spf outcomes.
auth_results sits alongside, carrying the raw SPF and DKIM results with the domains they were evaluated for, and identifiers carries the header_from domain.
Here is the distinction that decides whether you diagnose correctly. The dkim and spf values inside policy_evaluated are alignment results. The values inside auth_results are authentication results. A record showing auth_results with SPF passing while policy_evaluated reports SPF failing is not a contradiction and not a receiver bug — it is the signature of an alignment failure, and it means the check succeeded for a domain that is not yours. Reading the wrong pair sends you to fix a DNS record that was never broken.
The triage that works: sort records by count descending and take the top ten. For each source_ip, answer one question — is this mine. Your own mail servers, your CRM, your invoicing system, your helpdesk. Anything sending real volume that you recognise and that fails alignment is a system to fix. Anything you do not recognise is either a forwarder or a spoofer, and volume plus geography usually tells you which. The step-by-step setup for a cold outreach domain covers what to do with each category once identified.
Autocloz parses these reports rather than handing you the XML — though only as far as the reporting organisation, the date range and the pass/fail counts; it does not read the per-row source IP, so it tells you alignment is slipping without naming which sender did it — and its free plan covers 5 users and 10 mailboxes with SPF, DKIM and DMARC monitoring included — start free if the current process is opening ZIP files by hand.
Why your reports may never arrive at all
Two causes, and the first is invisible.
External destination verification. If the mailbox in your rua tag is on a different domain from the policy domain — a monitoring vendor, or a reporting alias at another company — the receiver will not simply send the report. It first constructs a hostname by taking the destination host, prepending _report._dmarc, and prepending your domain, then queries that name for a TXT record. Only "if at least one TXT resource record remains in the set after parsing" is the arrangement considered authorised. So a policy domain example.com reporting to a mailbox at reports.vendor.example requires a TXT record published at example.com._report._dmarc.reports.vendor.example by the vendor. Without it, conforming receivers send nothing, silently, and your inbox stays empty while everything looks correct on your side.
Volume. Not every receiver sends aggregate reports for every domain, and small senders often fall below whatever internal threshold a receiver applies. An empty report inbox on a domain sending a few hundred messages a day is not evidence of a broken record. Verify the record resolves before assuming the reporting is broken, and check what each of your three records actually returns before changing anything.
What DMARC does not do, and what Autocloz does not do here
DMARC protects the exact domain in the From header and nothing adjacent to it. It does nothing about a lookalike domain, a display name reading like your CEO with an unrelated address behind it, or a cousin domain registered last week. Those are different attacks with different mitigations.
It does not protect message content. A DMARC pass says the From domain was authorised; it says nothing about whether the body is honest.
It breaks under indirect mail flows. A mailing list that rewrites the subject line invalidates the DKIM signature, and a forwarder relaying from its own IP address invalidates SPF, so a legitimate message can fail DMARC because it was forwarded. The mitigation is the Authenticated Received Chain, published as RFC 8617 in July 2019 and still Experimental, which lets each intermediary record the authentication result it observed. Support is uneven, and a strict policy will lose some legitimate forwarded mail. That is a real cost to weigh, not a footnote.
And DMARC does not decide placement. Passing it removes a reason to filter you; it does not create a reason to deliver you. Complaint rate, sending volume and domain reputation continue to run the decision, and vendors positioning DMARC monitoring as a deliverability product — the category the Folderly comparison page sits in — are selling one input to a larger system.
Autocloz specifically: its email sending stack monitors your SPF, DKIM and DMARC records and parses aggregate reports — but be precise about how far that goes: it reads the reporting organisation, the date range and the pass/fail counts, and it does not read the per-row source IP or header-from, so it can tell you that alignment is slipping without telling you which sender is doing it. Naming the culprit is still a job for a full report parser. It does not request failure reports, because ruf exposes message content for limited diagnostic value. It cannot see reports from receivers that choose not to send them, so an absence in the data is not evidence of an absence of mail. And it cannot tell you whether an unrecognised sending IP is a forwarder or an attacker — that judgement stays yours, and the report gives you the volume and the timing to make it.
Frequently asked
What does DMARC actually do?
DMARC lets the owner of a domain publish, in DNS, what a receiving mail server should do with a message that claims to come from that domain but fails to prove it. It also asks receivers to send back reports about who is sending mail as the domain. It does not authenticate anything itself — it reads the results SPF and DKIM already produced and checks whether either one covers the domain a human sees in the From header.
Is DMARC still RFC 7489?
No. In May 2026 the IETF published RFC 9989, which obsoletes RFC 7489 and RFC 9091 and promotes DMARC from Informational to Standards Track for the first time. Aggregate reporting moved into RFC 9990 and failure reporting into RFC 9991. The three together are what implementers now build against, though existing records published under RFC 7489 keep working.
What is DMARC alignment and why do messages fail it while passing SPF?
Alignment is the requirement that the domain a check authenticated matches the domain in the visible From header. SPF authenticates the envelope return path and DKIM authenticates the signature's d= domain, and neither is necessarily your From domain. A message relayed by a sending platform commonly passes SPF for the platform's own domain, which authenticates something true about the platform and nothing about you.
Why am I not receiving DMARC aggregate reports?
The most common technical cause is missing external destination verification. If the reporting mailbox in your rua tag sits on a different domain from the policy domain, the receiver must first find a TXT record at a name combining your domain with _report._dmarc under the destination domain, and sends nothing if that record is absent. The other common cause is simply low volume, since not every receiver reports on small senders.
What replaced the pct tag in DMARC?
RFC 9989 removed pct entirely. Staged rollout is now expressed through the policy tags themselves — sp for subdomains, np for non-existent subdomains — and through the new t tag for test mode. A record still carrying pct will be tolerated by most receivers, but new deployments should not rely on partial application of a policy.
Does a DMARC policy of p=none do anything useful?
Yes, as an instrument rather than as a defence. At p=none receivers apply no special handling to failing mail but still send aggregate reports, which is the only practical way to discover every system sending as your domain before you tighten the policy. Publishing p=none also satisfies bulk-sender requirements that ask for a DMARC record without specifying a disposition.