← Back home

2026.08 / DMARC reporting 039

How to Read DMARC Aggregate Reports for Docker Mailserver

You added an rua=mailto: address to DMARC, and now compressed XML attachments arrive from Google, Microsoft, Yahoo, or other receivers. They look like machine noise. In fact, they answer a useful operational question: who sent mail claiming to be from your domain, and did SPF or DKIM align with that visible From domain?

For a Docker Mailserver installation, these reports help distinguish direct VPS delivery from a smarthost, web application, support tool, forgotten provider, forwarding path, or unauthorised source. They do not contain message bodies. They are aggregate counts grouped by source and authentication outcome.

Do not jump from one unfamiliar source address to a block rule. First identify the mail stream, read alignment separately from raw SPF and DKIM results, and compare several days of reports.

What a DMARC aggregate report tells you

RFC 7489 defines aggregate feedback as XML. A report normally covers a time window and contains one or more rows. Each row can include:

Google notes that aggregate reports are usually sent daily to the addresses in the DMARC rua tag. Not every receiver sends them, reporting intervals can vary, and a missing report is not proof that no mail was sent.

Receive reports without weakening mail security

A monitoring record might conceptually look like this:

_dmarc.example.com. TXT \
  "v=DMARC1; p=none; rua=mailto:[email protected]; adkim=r; aspf=r"

Use a mailbox or alias you control. Keep the actual reports private: aggregate XML can reveal sending services, volumes, source addresses, domain names, and report identifiers. Do not publish raw files, mailbox credentials, private keys, or unredacted infrastructure details.

p=none is a monitoring policy, not an authentication fix. It lets you inventory mail before asking receivers to quarantine or reject failures. If the rua mailbox is outside the domain publishing DMARC, receivers normally look for an additional DNS authorisation record at the report destination; use the cross-domain reporting rules in RFC 7489 rather than assuming the address will work.

Open the attachment safely

Reports commonly arrive as .xml.gz or .zip files. Work in a private directory, list an archive before extracting it, and avoid feeding sensitive reports to an unknown online converter.

# Gzip report: inspect without creating another file
gzip -cd report.xml.gz | less

# Zip report: list first, then print one known XML member
unzip -l report.zip
unzip -p report.zip report.xml | less

# Format XML locally when xmllint is installed
gzip -cd report.xml.gz | xmllint --format - | less

Treat emailed archives as untrusted input. Do not run scripts found inside them. A real aggregate report should be XML data, not an executable. Keep limits around automated parsers and reject unexpected file types or enormous decompressed payloads.

Read the report in four passes

1. Confirm scope and policy

Start with report_metadata, date_range, and policy_published. Check that the report covers the intended domain and period. Then note:

FieldMeaning
pRequested policy for the organisational domain.
spRequested policy for subdomains, when specified.
adkimRelaxed or strict DKIM identifier alignment.
aspfRelaxed or strict SPF identifier alignment.
pctPercentage of failing mail to which policy was requested to apply.

If these values differ from what you expect, query _dmarc.example.com through public resolvers. A report reflects what that receiver discovered during its reporting window, so an older report can legitimately show the policy before a recent DNS change.

2. Group rows into real mail streams

For each record, read row/source_ip and row/count, then the identifiers/header_from value. The source is the system the receiver observed delivering mail. It may be your direct mail host, a relay, a SaaS sender, or the last forwarder in an indirect route.

Do not identify ownership from reverse DNS alone. Compare the row with your private sender inventory, provider documentation, Docker Mailserver logs, smarthost settings, application configuration, and representative received headers. One business service can use many addresses, and one address range can serve many customers.

3. Separate authentication from alignment

This is the part most quick summaries get wrong. A report can show an underlying authentication pass that does not satisfy DMARC:

Under relaxed alignment, related subdomains can align at the organisational-domain level. Strict alignment requires exact domain matching. That means spf=pass for an unrelated provider bounce domain can appear beside policy-evaluated spf=fail. Both statements can be accurate: SPF authenticated something, but not an identity aligned with From.

4. Read disposition and overrides

The policy_evaluated/disposition value records what happened under DMARC processing. With p=none, a failing row will normally still show none; it does not mean authentication passed. Under enforcement, quarantine or reject can appear.

A receiver can also report a policy override, such as a locally trusted forwarder or mailing-list path. An override is evidence about that receiver’s handling, not proof that your sender configuration is correct. RFC 7960 explains why forwarding and mailing lists can disrupt SPF or DKIM and complicate DMARC results.

A small annotated XML example

<record>
  <row>
    <source_ip>192.0.2.10</source_ip>
    <count>12</count>
    <policy_evaluated>
      <disposition>none</disposition>
      <dkim>pass</dkim>
      <spf>fail</spf>
    </policy_evaluated>
  </row>
  <identifiers>
    <header_from>example.com</header_from>
  </identifiers>
  <auth_results>
    <dkim>
      <domain>example.com</domain>
      <selector>selector1</selector>
      <result>pass</result>
    </dkim>
    <spf>
      <domain>bounce.sender-service.example</domain>
      <scope>mfrom</scope>
      <result>pass</result>
    </spf>
  </auth_results>
</record>

192.0.2.10 is a documentation-only address. In this example, 12 messages pass DMARC through aligned DKIM. The provider’s SPF identity passes authentication but does not align with example.com, so policy-evaluated SPF is fail. The final disposition is none, which is expected under monitoring and is not itself a pass/fail verdict.

Turn rows into an action table

Keep a private table for at least several representative reporting days:

StreamKnown?Aligned SPFAligned DKIMAction
Direct Docker Mailserver deliveryYesPassPassKeep and monitor.
Application senderYesFailPassConfirm DKIM remains stable; fix custom return path if useful.
Old serviceConfirmed retiredFailFailRemove authorisation and credentials; watch for recurrence.
Unknown sourceNoFailFailInvestigate; do not authorise merely to clear the report.

Counts matter. A single low-volume forwarding failure needs different treatment from a large legitimate transactional stream. Also look for trends: a new selector, sudden volume, changed source range, or a known stream losing its only aligned mechanism.

Common Docker Mailserver findings

When to move from monitoring to enforcement

Do not choose enforcement because a dashboard turns green. Move deliberately when every legitimate mail stream is inventoried, each has at least one durable aligned pass, unknown failures are understood, report collection works, and you have rollback ownership. Increase policy in stages and continue reading reports after every change.

Before changing DMARC, test fresh messages from Docker Mailserver and each third-party route. Inspect the recipient’s original Authentication-Results alongside aggregate reports. Aggregate XML is excellent for coverage and trends, but one received message gives transaction-level headers and confirms what a real route produced now.

Compact report-reading checklist

  1. Store report attachments privately and inspect archives safely.
  2. Confirm reporting organisation, domain, date range, and published policy.
  3. Group source rows into known, retired, forwarded, and unknown streams.
  4. Compare header_from with underlying SPF and DKIM domains.
  5. Read policy-evaluated alignment separately from raw authentication results.
  6. Account for disposition and documented receiver overrides.
  7. Compare several days and weight findings by count and business importance.
  8. Repair legitimate streams; never authorise an unknown sender just to remove a failure.
  9. Verify changes with fresh received mail before tightening DMARC policy.

The authoritative format and field definitions are in RFC 7489, with indirect-mail interoperability context in RFC 7960. Google’s DMARC reports overview explains its reporting workflow, while Docker Mailserver’s current SPF, DKIM, and DMARC documentation covers the server-side setup. Use documentation matching your pinned Docker Mailserver image.