A DMARC record with a rua= tag starts producing daily email attachments within hours. Each attachment is a gzipped XML file from a single mailbox provider (Google, Microsoft, Yahoo, Comcast, Mail.ru, and any other receiver that processed mail claiming to be from the domain in the past 24 hours). The XML is structured, well-defined (RFC 7489 section 7.2), and not at all obvious.
This is the moment most WordPress operators give up on DMARC. The policy is set, the reports start arriving, the data is unreadable, and either the policy stays at p=none forever (passive, no enforcement) or the rua tag gets deleted (no visibility, no enforcement). Using the reports instead means three actions: identify which servers are sending mail as the domain, see what is passing and failing authentication, and tighten policy from p=none to p=quarantine to p=reject with confidence.
What an aggregate report tells you
A single aggregate report answers one question: in the period this report covers (typically 24 hours), what messages did this one mailbox provider see from this domain, and what did each fail or pass authentication?
The diagnostic value is the cross-reference between sources and outcomes. A WordPress site sending through Postmark for transactional mail, a contact-form plugin that bypasses wp_mail() and calls PHP’s mail() directly, a MailerLite list for marketing, and a backup MTA from cPanel hosting will appear as four distinct sets of IPs in the reports. The reports tell you which of those four are passing DMARC alignment and which are not, and the IP addresses tell you which sender each row represents.
What the reports do not tell you: which specific messages were involved (no subject lines, no recipients, no content), whether messages reached the inbox after passing authentication, or what happened on the receiving end after the DMARC verdict. They are policy-evaluation summaries by source IP and authentication result, aggregated over a time window. That scope is the source of both their usefulness (one daily summary per receiver) and their limits (no per-message detail).
For the SPF / DKIM / DMARC mechanics this piece builds on, see the DNS setup guide and the first-principles email reference.
How reports arrive and how to read them without opening attachments
Reports arrive as email attachments to whatever address is published in the rua= tag of the DMARC record. The attachments are gzipped XML, occasionally zipped, with filenames in the form google.com!example.com!1719360000!1719446400.xml.gz (sender org, reported domain, period start unix, period end unix). Opening one in a text editor produces a few hundred lines of well-formed XML per receiver per day. On a domain that sends any meaningful volume, that adds up to dozens of attachments per day from a dozen receivers. Manual reading does not scale.
Three paths cover the work:
Paid hosted parsers ingest the reports automatically (forward them to the parser’s intake address, or grant IMAP access to the rua mailbox) and present a dashboard.
DMARC Analyzer,
Postmark DMARC Monitoring, and
EasyDMARC are the three the WordPress audience encounters most often. Postmark’s offering is free for the basic report ingestion and is the simplest path for a small site that already uses Postmark. The others are paid tiers with longer retention and additional features.
Self-hosted parsers put the work on a server you control.
parsedmarc is the most actively maintained open-source option: a Python tool that ingests reports from an IMAP mailbox, parses them, and writes the data to Elasticsearch / Splunk / a JSON file / a Kafka topic. The setup is a Python virtualenv, an IMAP account, and a cron job; the trade-off is the operator runs and updates the pipeline themselves, including the dashboard layer.
Manual reading, for low-volume sites or one-off diagnostics: gunzip the attachment, open the XML in any editor, and walk through the structure. This piece teaches that walk so the operator can do it regardless of which tooling they pick.
nanoPost recommends parsedmarc for sites that want a no-vendor-lock path, Postmark DMARC Monitoring for sites already using Postmark or that want zero setup, and the paid tiers when the site sends enough volume that the dashboards and retention pay for themselves. None of the three is the wrong choice; the differences are in setup cost, ongoing maintenance, and the depth of the analytics surface.
Walking through a representative report
The walkthrough below uses an illustrative report constructed against the RFC 7489 schema. The IPs are real published sender IPs from each vendor’s documented lists; the field shapes are exactly what a real Google-issued report contains; and the three records cover the three patterns that explain the rest of the field. The domain example-wp.com stands in for a real WordPress site, and the report identifiers and counts are illustrative.
<?xml version="1.0" encoding="UTF-8" ?>
<feedback>
<report_metadata>
<org_name>google.com</org_name>
<email>[email protected]</email>
<extra_contact_info>https://support.google.com/a/answer/2466580</extra_contact_info>
<report_id>16182841337028756143</report_id>
<date_range>
<begin>1718668800</begin>
<end>1718755199</end>
</date_range>
</report_metadata>
<policy_published>
<domain>example-wp.com</domain>
<adkim>r</adkim>
<aspf>r</aspf>
<p>quarantine</p>
<sp>quarantine</sp>
<pct>100</pct>
<np>reject</np>
</policy_published>
<record>
<row>
<source_ip>50.31.156.6</source_ip>
<count>147</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>pass</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>example-wp.com</header_from>
</identifiers>
<auth_results>
<dkim>
<domain>example-wp.com</domain>
<result>pass</result>
<selector>20240101</selector>
</dkim>
<spf>
<domain>example-wp.com</domain>
<result>pass</result>
</spf>
</auth_results>
</record>
<record>
<row>
<source_ip>185.41.28.109</source_ip>
<count>23</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>fail</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>example-wp.com</header_from>
</identifiers>
<auth_results>
<dkim>
<domain>example-wp.com</domain>
<result>pass</result>
<selector>mail</selector>
</dkim>
<spf>
<domain>relay.brevo.com</domain>
<result>pass</result>
</spf>
</auth_results>
</record>
<record>
<row>
<source_ip>45.79.187.22</source_ip>
<count>4</count>
<policy_evaluated>
<disposition>quarantine</disposition>
<dkim>fail</dkim>
<spf>fail</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>example-wp.com</header_from>
</identifiers>
<auth_results>
<dkim>
<domain>example-wp.com</domain>
<result>fail</result>
</dkim>
<spf>
<domain>otherhost.example</domain>
<result>fail</result>
</spf>
</auth_results>
</record>
</feedback>
Three records, three distinct stories. Walking through each:
<report_metadata>: Google sent this report on behalf of [email protected], covering the 24-hour window starting 1718668800 (Unix timestamp, in this example 2024-06-18 00:00 UTC) and ending 1718755199 (2024-06-18 23:59:59 UTC). The report_id is Google’s identifier; you do not need to do anything with it unless you are deduplicating against a previously ingested report.
<policy_published>: The current DMARC record for example-wp.com is v=DMARC1; p=quarantine; sp=quarantine; pct=100; adkim=r; aspf=r; np=reject. p=quarantine is the main policy, pct=100 means it applies to every message, adkim=r and aspf=r are relaxed alignment (the most common), and np=reject is the policy for non-existent subdomains (a DMARCbis addition with partial receiver support as of mid-2026; receivers that respect it will reject mail claiming to be from random.example-wp.com outright).
First <record> (147 messages from 50.31.156.6): an IP from Postmark’s published sending range. The policy_evaluated/disposition is none (the receiver applied no penalty), dkim and spf both passed. The auth_results confirm: DKIM passed with selector 20240101 signing for example-wp.com, and SPF passed for example-wp.com‘s envelope-from. This is the easy case: every authentication aligned, the receiver applied no penalty, nothing to fix.
Second <record> (23 messages from 185.41.28.109): an IP from Brevo‘s egress range (whois confirms MailinBlue / Sendinblue, France; Brevo is Sendinblue rebranded). The disposition is none (no penalty), but the picture is more nuanced: dkim evaluated as pass, spf as fail. The auth_results reveal why: DKIM signed for example-wp.com, aligned with the From domain, so DKIM passes both raw and aligned. SPF, however, passed for relay.brevo.com, which is the envelope-from Brevo uses for tracking and bounce handling. Since relay.brevo.com does not align with the header-from example-wp.com, SPF passes the raw check but fails the alignment check. DMARC requires either SPF or DKIM to align; DKIM alignment is sufficient here, and the message passes DMARC overall. This is the working case for relays that use their own envelope domain: DKIM carries the alignment, SPF does not, and that is fine.
Third <record> (4 messages from 45.79.187.22): an unrecognised IP. The disposition is quarantine (the receiver moved these to spam), DKIM and SPF both failed alignment, and the auth_results show DKIM failed and SPF was checked against otherhost.example, a domain unrelated to example-wp.com. Four messages, quarantined. This is what an impersonation attempt looks like: someone sent mail claiming to be from example-wp.com from an unrelated server, and DMARC enforcement caught it. Nothing to fix; the policy worked as designed.
Field-by-field action map
Every field in a DMARC report maps to a decision the WordPress operator can make. The fields in order of importance:
source_ip: the most important field. WhoIs each unique IP that appears with a non-trivial count. Map to known senders (the SMTP relays you have configured, the mailer plugin’s transport, any third-party newsletter or transactional services). Postmark publishes its sending IPs at
postmarkapp.com/support/article/800-ips-for-firewalls; Brevo publishes its IP ranges in its help centre; SendGrid lists ranges per dedicated-IP tier; Amazon SES uses the AWS IP ranges JSON. For the unidentified IPs that recur in reports, run whois on the IP and check the ASN. A consistent unknown source warrants investigation: is it a relay you forgot about, a host’s transactional MTA you did not realise was sending, or an impersonation campaign?
policy_evaluated/disposition: what the receiver did. none means the receiver applied no penalty; quarantine means the message was treated as suspicious (typically delivered to a spam folder); reject means the message was refused outright. The disposition depends on the published policy (p=) and the receiver’s local override behaviour. A quarantine disposition on a message you sent is a signal worth investigating; a quarantine disposition on a message you did not send is the policy working.
policy_evaluated/dkim and policy_evaluated/spf: the aligned authentication results. These are what DMARC uses for its verdict, and they are not the same as the raw auth_results below. Both pass is the happy case. One pass is sufficient for DMARC to pass. Both fail is a DMARC failure.
auth_results/dkim: the raw DKIM check. The domain element here is the domain that signed the message. If that domain matches the From-header domain (per the alignment rule, relaxed or strict), DKIM alignment passes. The selector element identifies which DKIM key was used. A failed DKIM result with domain matching your domain usually means the receiving server could not retrieve the public key (DNS lookup failed) or the signature did not verify (the message body was modified in transit, or the key in DNS does not match the key the sender used).
auth_results/spf: the raw SPF check. The domain is the envelope-from (Return-Path) domain, which is not always the same as the From-header domain. A relay that uses its own envelope-from will pass SPF for that envelope domain and fail SPF alignment. If DKIM aligns, the message still passes DMARC. If neither aligns, the message fails DMARC even if both raw checks pass.
The alignment vs raw distinction is where most operators get confused. A row that shows auth_results/spf as pass but policy_evaluated/spf as fail is not a contradiction: the SPF check itself passed (the sending server was authorised by the envelope-from domain’s SPF record), but the envelope-from domain does not align with the header-from. Alignment is the DMARC-specific test layered on top of the underlying SPF/DKIM checks. The policy_evaluated element is the only one that affects DMARC enforcement.
Common scenarios in WordPress reports
After a few weeks of reports, recurring patterns emerge. The four most common, with the diagnostic and action for each:
Scenario 1: all your relays pass, all unknown IPs fail. Every known sender (the SMTP relay, the mailer plugin’s IP if direct-from-WP, any newsletter platform) appears with both DKIM and SPF aligned and disposition=none. Unknown IPs appear with both failing and disposition=quarantine or reject depending on the policy. This is the readiness signal: the policy is correctly catching impersonation while not affecting legitimate mail. The operator can tighten from p=none to p=quarantine, or from p=quarantine to p=reject, with confidence. Typical timeline from p=none to p=reject for a small site: 4 to 6 weeks across the report cycle, ratcheting pct from 10 to 25 to 50 to 100 between policy changes if extra caution is warranted.
Scenario 2: a relay you forgot about is failing. Reports show consistent failures from an IP that traces to a service the operator forgot was sending mail. Common cases: an old MailerLite or Mailchimp account that still has the domain configured, a hosting provider’s transactional MTA (cPanel’s exim, for example) that the site has not been reconfigured to bypass, a contact-form plugin sending through wp_mail() directly with no SMTP plugin configured, or a CRM integration sending notifications. The fix is to either add the service to SPF and configure DKIM signing (if the service is legitimate and ongoing), or to disable the sending from that service. Until the fix lands, raising the DMARC policy means losing the mail this service was producing.
Scenario 3: high volume from random IPs, all failing. Hundreds or thousands of messages per day from a wide range of unrelated IPs, all failing both SPF and DKIM, all quarantined or rejected. This is a spam impersonation campaign: someone is sending mail claiming to be from your domain to large recipient lists. DMARC is working as designed: the receivers are catching it and the legitimate domain is not getting blacklisted. No action required beyond confirming none of the failing IPs are your own. The campaign typically subsides on its own within a week or two when the spammer moves to a different target domain.
Scenario 4: an expected relay is failing alignment despite passing SPF. This is the trickiest one. A known sending service (a newsletter platform, a transactional relay) shows in reports with raw SPF passing but policy_evaluated/spf failing, and DKIM also failing. The diagnostic: the relay is sending with its own envelope-from (causing SPF alignment to fail) and signing DKIM for its own domain rather than yours (causing DKIM alignment to fail). The fix is to configure DKIM signing on the relay so it signs with a selector under your domain; the exact steps vary by relay, but most major platforms support this and document it. Until the DKIM is fixed, the relay’s messages will keep failing DMARC alignment regardless of how clean SPF looks.
Tightening the policy
DMARC enforcement happens in stages, with the pct tag as the safety mechanism for each step.
Start at p=none. Reports flow, the operator parses them for two to four weeks, identifies the senders, and verifies that all legitimate senders are aligning correctly (one of SPF or DKIM aligned, ideally both). Unknown failures should account for a small fraction of total volume and should match the spam-impersonation pattern (random IPs, never recurring).
Move to p=quarantine; pct=10. Now 10% of messages that fail alignment are quarantined; 90% are still delivered (the pct test selects randomly). Watch the reports for a week. The expected outcome: continued failures from spam IPs (now quarantined for 10% of attempts) and zero new failures from legitimate senders.
Ratchet up: pct=25, then 50, then 100, with about a week between each step for a low-volume site. Faster ratcheting is possible for sites with high enough volume that a week of data covers all sending patterns.
Move to p=quarantine; pct=100, hold for two weeks, then move to p=reject; pct=100. At reject, failed messages are refused outright at the SMTP transaction. This is the strongest setting and the goal for a domain that wants spoofing prevention to be airtight.
A WordPress site that sends only through one well-configured relay typically reaches p=reject in four to six weeks. A site with three or four sending services and a more complicated mail flow takes longer, often two to three months, because each service needs its alignment verified independently. The pct ratchet ensures the operator can roll back if a previously unnoticed sender starts failing after a tightening step.
What aggregate reports do not tell you
Aggregate reports cover policy evaluation, not message content. They do not include the subject line, body, recipient list, or any header content beyond the From, the authenticated DKIM-signed identifier, and the SPF envelope-from. If a specific message is failing DMARC and you need to see why at the per-message level, aggregate reports cannot answer that.
Forensic (failure) reports via the ruf= tag are the per-message detail layer. They include a copy of the failing message and the authentication details. The catch in 2026: most major receivers (Google, Microsoft, Yahoo) no longer send forensic reports for privacy reasons, so adding a ruf= tag often produces little or no traffic. Smaller receivers and some corporate mail servers still send them. The aggregate-only fallback is to roll out enforcement gradually with pct ratcheting and to investigate by sending test messages from each suspected source.
Aggregate reports do not tell you about forwarded mail. A message that goes from your site to a recipient who forwards it on (a mailing list, a contact-form auto-reply that gets forwarded to a team alias) will fail SPF at the second hop (the forwarder’s IP is not in your SPF record) and may fail DKIM if the forwarder modifies the body. The reports show the forwarder’s IP and an aligned-DKIM-pass / SPF-fail row, which can look alarming but is normal for forwarded traffic. ARC (Authenticated Received Chain, RFC 8617) is the standard for preserving authentication through forwards; receiving servers that implement it can re-evaluate DMARC for forwarded mail. ARC is implemented by sending services and forwarders, not by site operators.
Finally, the reports do not tell you whether a message reached the recipient’s inbox. A DMARC-pass message can still be filtered to spam based on content, sender reputation, or receiver-specific policy. DMARC alignment is necessary but not sufficient for inbox placement. The SMTP session log reference covers the relay-side delivery confirmation; for inbox placement specifically, a seedlist test (sending to a known set of mailboxes and checking each) is the only direct measurement.
For the SPF / DKIM / DMARC system overview, first-principles email reference. For setting the records, DNS setup for WordPress email.
