Reporting — the rua Tag

Reporting — the rua tag

The rua= tag is the address that receives DMARC aggregate reports. Without it, the policy is operating in the dark — you have no signal on what mail is failing alignment, who is sending it, and whether your move to p=quarantine or p=reject is breaking anything legitimate.

Cathedra warns when the tag is missing. This lesson covers what the reports actually look like and how to consume them.

What Cathedra reports

DmarcRecordCheck.php parses the DMARC record and checks for the presence of a rua tag. If it is absent or empty, the check emits:

Field Value
status warning
severity low
finding “No rua (aggregate report) address configured. DMARC feedback will not be received.”
recommendation “Add rua=mailto:dmarc-reports@yourdomain.com to receive aggregate reports.”

Severity is low because the policy itself still functions — receivers will still apply p=reject or p=quarantine. What you lose is visibility. That is correctable, not catastrophic, which is why this finding is a warning at low severity rather than an error.

A complete DMARC record with reporting:

v=DMARC1; p=reject; rua=mailto:dmarc@isidoregroup.com

You can list multiple addresses, comma-separated:

v=DMARC1; p=reject; rua=mailto:dmarc@isidoregroup.com,mailto:dmarc-isidoregroup@dmarcian.com

The second pattern is common — one address goes to the client for archival, the other goes to a reporting service for parsing.

What an aggregate report actually contains

A DMARC aggregate report is an XML file. Receivers (Google, Microsoft, Yahoo, ProtonMail, and so on) produce one report per day per sending domain that produced traffic, and email it to every address in rua=. The file is usually gzipped and attached to the email.

The structure, simplified:

<feedback>
  <report_metadata>
    <org_name>google.com</org_name>
    <email>noreply-dmarc-support@google.com</email>
    <report_id>1234567890</report_id>
    <date_range>
      <begin>1715212800</begin>
      <end>1715299200</end>
    </date_range>
  </report_metadata>
  <policy_published>
    <domain>isidoregroup.com</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>quarantine</p>
    <pct>100</pct>
  </policy_published>
  <record>
    <row>
      <source_ip>40.92.4.21</source_ip>
      <count>142</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>pass</dkim>
        <spf>pass</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>isidoregroup.com</header_from>
    </identifiers>
    <auth_results>
      <dkim>
        <domain>isidoregroup.com</domain>
        <result>pass</result>
      </dkim>
      <spf>
        <domain>isidoregroup.com</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
  <!-- additional <record> blocks for each source IP that sent mail -->
</feedback>

Each <record> block represents traffic from one source IP to that receiver during the 24-hour window. The fields you read most:

  • <source_ip> — who sent it.
  • <count> — how many messages.
  • <header_from> — what From: domain they claimed.
  • <dkim> and <spf> results, plus whether each aligned with the From: domain.
  • <disposition> — what the receiver actually did (none, quarantine, reject).

The signal you care about for a DMARC ramp is anything in <auth_results> that shows pass for SPF or DKIM but the <policy_evaluated> shows disposition=quarantine or reject. That is a message that authenticated against some domain but failed to align with the From: header. Those are your third-party senders that need attention.

Reading reports by hand vs. tooling

The XML is parseable by hand for small domains — a small business might produce three or four reports a day, each with five to ten records. Open the gzip, scan the source IPs, recognize legitimate senders, flag anything unknown.

For anything larger, you want tooling. The reports are well-structured but voluminous. A 500-user domain might produce hundreds of records a day across all receivers.

The tools we use at Isidore:

  • dmarcian — the industry standard. Free tier exists for low volume. Paid tier handles enterprise scale. UI is built for DMARC ramps specifically; flags failing-but-legitimate-looking senders, classifies known third parties, shows alignment trends over time.
  • Postmark DMARC Digests — weekly digest emails sent in human-readable form. Free. Lower density than dmarcian but useful for clients who want to see something themselves.
  • Valimail — enterprise-grade. The platform of choice when a domain has dozens of third-party senders and the engagement includes ongoing DMARC operation as a service.

For most MSP clients we land on dmarcian. It is enough tooling to operate the ramp confidently without overhead.

Setup pattern we use

On an Isidore-managed domain, the rua address is dmarc-reports@{client-domain}, forwarded by a mail rule to an Isidore-monitored shared mailbox or directly into dmarcian. We never use the client’s primary mailboxes — DMARC reports are noisy and operational, not a thing the client should see day-to-day.

If the client is paying for dmarcian, the address is one we get from the dmarcian admin panel, in the form dmarc-{clientid}@dmarcian.com. We add that as a second rua value, so we have both archival in the client’s domain and parsing in dmarcian.

A note on ruf

There is a sibling tag, ruf=, for forensic reports — per-message failure reports rather than aggregates. Cathedra does not check for ruf, and we generally do not configure it. Forensic reports contain message-level content, which raises privacy questions, and many receivers do not send them at all. Aggregate is sufficient for an operational ramp.

What you should remember

  • rua= is the address that receives daily aggregate DMARC reports. Without it, you are flying blind through the ramp.
  • Cathedra warns at low severity when rua is missing. Finding: “No rua (aggregate report) address configured. DMARC feedback will not be received.”
  • Reports are XML, gzipped, emailed daily by each receiver. Each <record> is traffic from one source IP for one receiver.
  • The signal you read: messages where SPF or DKIM passed for one domain but did not align with the From: header. Those are third-party senders that need fixing.
  • For most clients, dmarcian is the tool. Set rua= to a forwarder under the client’s domain plus the dmarcian intake address.

Cathedra alignment: DmarcRecordCheck.php — the third finding the check produces, when rua is empty