DMARC Reports: Parse Aggregate Data and Find Alignment Failures

· Published · 14 min read

DMARC aggregate XML reports from receivers parsed and normalized into source IP SPF alignment DKIM alignment policy disposition groups trends and investigations

DMARC aggregate reports are receiver-generated summaries of messages claiming to use a domain. They reveal source IPs, message counts, authentication outcomes, alignment and policy disposition, but they do not contain message bodies or prove that every source is malicious or legitimate. Analysis should normalize reports, map sources to accountable services, investigate alignment failures and advance policy only after required mail streams are understood.

Publish reporting addresses and govern intake

A DMARC record can request aggregate reports with rua=mailto:[email protected]. Use a dedicated, secured mailbox or processor that can handle compressed XML and validate external report authorization when reports are sent to another organizational domain. Apply malware-safe decompression limits and retain original files with checksums.

Deduplicate by reporting organization, report ID and date range. Reporting coverage varies, so absence from reports does not prove absence of traffic.

Normalize the XML without losing provenance

report_metadata: org_name, report_id, begin, end
policy_published: domain, adkim, aspf, p, sp, pct
record.row: source_ip, count, disposition, dkim, spf, reason
identifiers: header_from, envelope_from, envelope_to
auth_results: dkim domain/selector/result; spf domain/scope/result

Store raw and parsed forms, parser version and validation errors. One row represents an aggregate count, not one message. Keep unknown values instead of coercing them to pass or fail.

Separate authentication from alignment

SPF can pass for an envelope domain yet fail DMARC when it is not aligned with the visible From domain. DKIM can pass for a vendor signature and still be unaligned. DMARC needs one aligned passing mechanism. Evaluate organizational-domain and strict/relaxed mode according to the published policy.

SPF alignedDKIM alignedDMARC
YesNoPass
NoYesPass
NoNoFail
Authentication errorNoInvestigate failure/temperror context

Map every material source to an owner

Group by source IP, reverse DNS, ASN, header From, authenticated domains and selector. Label as approved direct infrastructure, approved vendor, forwarding/intermediary, unauthorized, unknown or decommissioned. Require a service owner, business purpose, expected volume and remediation plan.

Do not allowlist an IP merely because volume is high. Shared cloud addresses can represent many tenants, and an attacker can send from infrastructure with good reputation. Authorization depends on the contracted sending route and aligned identity.

Investigate failure patterns

  • SPF pass, DMARC fail: envelope domain likely unaligned; configure a custom return path or aligned DKIM.
  • DKIM fail after forwarding: body/header modification may break the signature; inspect ARC and intermediary behavior.
  • Unknown source, both fail: likely unauthorized use, but confirm internal and vendor inventories.
  • Disposition none despite reject policy: examine receiver override reasons and report semantics.
  • Sudden volume jump: check campaign, compromised system, new vendor or spoofing.

Advance policy using measured readiness

Begin with monitoring, correct legitimate streams, then use a controlled percentage or subdomain scope where appropriate. Before quarantine or reject, quantify aligned legitimate volume, unresolved high-value sources, report coverage and rollback criteria. Keep one aligned DKIM path resilient because forwarding can make SPF unreliable.

Enforcement blocks unauthorized direct use of the domain in From; it does not stop lookalike domains or every phishing technique. Continue brand monitoring and user protection.

Use the current DMARC and aggregate-report specifications

DMARC is now defined by RFC 9989, with aggregate reporting in RFC 9990 and failure reporting in RFC 9991. RFC 7489 is obsolete. Implementations and historical report generators can still reflect earlier behavior, so store report metadata and parser version rather than assuming every producer emits the same optional fields.

DMARC evaluates the visible RFC 5322 From domain and passes when at least one authenticated SPF or DKIM identifier aligns under policy. Aggregate reports summarize receiver observations by source and authentication disposition. They do not list inbox placement, individual complaints or every message.

Parse the DMARC DNS policy and reporting authorization correctly

_dmarc.example.com. 3600 IN TXT
 "v=DMARC1; p=quarantine; rua=mailto:[email protected]; pct=100"

external report authorization example:
example.com._report._dmarc.reports.example.net. IN TXT "v=DMARC1"

Publish one valid DMARC record at the correct owner name. Multiple records or malformed tags can make policy invalid. External reporting destinations require authorization under the reporting specification. Verify authoritative and recursive DNS, TXT concatenation, organizational-domain/subdomain behavior and mailbox/collector capacity.

Keep reporting addresses separate from personal mailboxes. Reports are untrusted attachments and can arrive compressed.

Treat aggregate reports as untrusted external files

RiskControl
Compression bombCompressed/expanded size, ratio and recursion limits
Malformed XMLDisable external entities/network access; schema-aware parser
Duplicate reportReporter, report ID, date range and payload checksum
Oversized row countBounded streaming parser and quarantine
Forged reporter metadataRetain transport evidence; do not trust XML contact as authentication
Unknown fields/enumsPreserve raw report and forward-compatible unknown state

Parse in an isolated worker without shelling out to filenames. Store raw payload checksum, MIME metadata, parser version and quarantine reason under restricted access.

Normalize reports without losing policy and identifier context

dmarc_report(
  reporter, report_id, begin_utc, end_utc,
  policy_domain, adkim, aspf, p, sp, pct,
  received_at_utc, raw_checksum, parser_version
)
dmarc_row(
  report_key, source_ip, message_count, disposition,
  dkim_eval, spf_eval, reason_type,
  header_from, envelope_from, envelope_to
)
dmarc_auth_result(
  row_key, mechanism, auth_domain, selector,
  scope, result, human_result
)

One row can contain several DKIM or SPF authentication results. Do not flatten them into a comma string. Retain policy-evaluated aligned results separately from mechanism results. Store IP in a type supporting IPv4/IPv6 and preserve reporter-specific unknown values.

Separate authentication pass from DMARC alignment

SPFDKIMDMARC interpretation
Pass, aligned MAIL FROMAnyPass through SPF alignment
Pass, unaligned vendor domainPass, aligned d=Pass through DKIM
Pass, unalignedPass, unalignedFail despite two mechanism passes
Fail after forwardingPass and alignedPass through DKIM
FailFail/missingFail; disposition depends on policy/local handling

Group by visible From, envelope domain, DKIM domain/selector, source IP and reporter. A vendor source can pass SPF but remain unauthorized for the brand’s DMARC identity.

Reconcile every observed source with an accountable sending service

Maintain authorized service, CIDR/IP, provider, stream, From domains, envelope domains, DKIM domains/selectors, owner and retirement date. Match report rows to the inventory with effective dates. “Known cloud provider” is not sufficient; identify the exact customer/service path.

Source stateAction
Authorized and alignedMonitor volume/authentication drift
Authorized but misalignedFix customer DKIM/return path before enforcement
Unknown low volumeInvestigate, do not ignore by percentage
Former vendor still activeStop credentials/routing and remove authorization safely
Forwarder/mailing listAssess path, ARC and expected authentication behavior

Track first/last seen and unexpected volume. An attacker or forgotten application can hide inside a 99% pass total.

Move policy toward enforcement with measured gates

  1. Inventory all legitimate sources and publish reporting.
  2. Establish stable report ingestion and source ownership.
  3. Correct aligned DKIM/SPF on every required route.
  4. Identify forwarded/list traffic and subdomain policy impact.
  5. Simulate proposed disposition by reporter/source.
  6. Increase enforcement scope under explicit business gates.
  7. Monitor bounces, support cases, aggregate reports and legitimate flows.

pct behavior and receiver local policy do not make partial rollout a perfect experiment. Preserve the published policy and effective time. Do not jump to rejection merely to improve a compliance dashboard while legitimate services still fail alignment.

Calculate report metrics with correct denominators

total_messages = SUM(row.message_count)
dmarc_pass = SUM(count WHERE policy_evaluated_dkim=pass
                         OR policy_evaluated_spf=pass)
pass_rate = dmarc_pass / total_messages

unknown_source_share = SUM(count WHERE source_owner IS NULL)
                       / total_messages

Segment by reporter, source, identity and date. Reports cover intervals and may arrive late or overlap; deduplicate before summing. An aggregate row count is messages represented, not recipients or unique messages. Publish coverage reporters, arrival lag, invalid/quarantined reports and unknown source share.

Worked case: 99.8% pass hides an unauthorized billing application

A domain appears healthy at 99.8% DMARC pass. The remaining 0.2% comes from a cloud range and is dismissed. Source reconciliation shows the same IP sends monthly billing notices from a recently acquired subsidiary. SPF passes for the SaaS vendor but is unaligned; its DKIM also uses the vendor domain.

The service is legitimate but incorrectly configured. Before moving to p=reject, operators configure a customer-aligned DKIM domain, test final received messages and verify the source appears aligned across several reporters. They also assign an owner and credentials retirement process.

The incident demonstrates why percent alone is unsafe. A small stream can contain legally or operationally critical messages, while an unknown malicious source can also remain statistically small.

Operate a daily DMARC review and incident path

  • Report intake success, duplicates, quarantine and arrival delay.
  • Message volume/pass by reporter and source.
  • Unknown/new IP, DKIM domain and selector.
  • Authorized-source alignment regression.
  • Policy/disposition changes and subdomain impact.
  • Forwarding/list patterns and ARC evidence.
  • Source owner, remediation ticket and verification date.

When a new source appears, preserve report rows, identify the application/credential and contain unauthorized sending. Do not add it to SPF before establishing ownership and purpose. Close after corrected/disabled behavior appears across matured reports.

Read the aggregate XML hierarchy before flattening it

<feedback>
 <report_metadata>...report_id/date_range...</report_metadata>
 <policy_published>
   <domain>example.com</domain><adkim>r</adkim>
   <aspf>r</aspf><p>reject</p><pct>100</pct>
 </policy_published>
 <record>
  <row><source_ip>192.0.2.25</source_ip><count>840</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>...one or more DKIM/SPF results...</auth_results>
 </record>
</feedback>

The policy-evaluated results express aligned DMARC evaluation. Authentication results can include several signatures or SPF identities and are not interchangeable. A disposition of none does not always mean published p=none; local policy, overrides and evaluation reasons matter.

Interpret disposition and policy override reasons cautiously

ObservationMeaningAction
DMARC fail, disposition rejectReceiver reports enforcement consistent with policy/local handlingIdentify source and legitimate impact
DMARC fail, disposition noneOverride/local policy or non-enforcement contextInspect reason fields and reporter behavior
DMARC pass, disposition noneNormal accepted authentication resultMonitor source ownership
Forwarded/mailing-list reasonReceiver reports an override rationaleAssess real path and ARC; do not globally allow

Reason type/comment is reporter-provided context, not a universal guarantee. Preserve unknown reasons. Policy disposition is not inbox placement and a rejected row does not identify every affected recipient.

Model organizational and subdomain policy boundaries

The visible From may be an organizational domain or a subdomain with its own DMARC record/policy behavior. Maintain an effective-policy resolver based on the current specification and Public Suffix List behavior rather than splitting on the last two labels. Internationalized domains require consistent A-label/U-label handling.

effective_policy(
  header_from_domain, organizational_domain,
  discovered_policy_domain, applied_p_or_sp,
  adkim, aspf, pct, discovery_version,
  public_suffix_data_version
)

Test exact-domain records, inherited subdomain behavior, delegated business units and non-existent names. Publishing sp=reject can affect forgotten subdomains and third-party services. Inventory them before enforcement.

Reconcile reports across receivers without double counting

Each reporter observes its own population, time boundary and receiver behavior. Deduplicate within reporter/report ID/date range, then aggregate only nonoverlapping records. Compare report message counts directionally with outbound accepted traffic by destination, recognizing forwarded mail, receiver grouping and reporting coverage.

DifferencePossible cause
Outbound volume greaterNonreporting receivers, report lag or different time boundary
Report volume greaterForwarded/resent traffic, overlap or unauthorized source
One reporter missingCollector failure, no eligible traffic or reporter delay
Sudden new source at several reportersNew service, compromise or shared route change

Do not scale reports to force equality. Publish a coverage inventory and freshness state.

Investigate an unknown source before authorizing it

  1. Preserve report rows, source IP, identities, selectors, reporters and dates.
  2. Check current and historical route/service inventory.
  3. Search application, cloud, ESP and security logs for the source.
  4. Determine whether it is forwarding, a forgotten vendor or unauthorized sending.
  5. Contain compromised credentials or infrastructure before DNS changes.
  6. For legitimate mail, configure aligned identity and test final artifacts.
  7. For unauthorized mail, let policy operate and monitor disappearance.

Adding an unknown IP to SPF can legitimize abuse and consume lookup budget. Establish ownership and envelope use first. A cloud netblock does not identify the tenant.

Test parser, policy and reports before an enforcement change

Create sanitized XML fixtures for IPv4/IPv6, multiple auth results, unknown reason, missing optional fields, external reporting, duplicate IDs, overlapping intervals and malformed/compressed payloads. Assert message counts, alignment, disposition and source ownership.

Before DNS release, send through every legitimate route to controlled receivers, inspect final Authentication-Results, and verify aggregate reports after their normal delay. Record policy TXT, TTL, effective organizational/subdomain behavior, report collector health and rollback condition. DNS rollback is not instant because caches persist.

After change, monitor legitimate bounce/support cases and report dispositions. Close only when required sources align across matured reporters and unknown traffic remains contained.

Monitor report-pipeline quality as a security control

Track expected reporters, arrival lag distribution, messages represented, duplicate rate, parser rejection, unknown enum/field, external authorization failure and storage freshness. A broken collector can make unauthorized traffic disappear from dashboards. Missing reports are unknown coverage, not zero failures.

AlertFirst check
All reporters stopMailbox/HTTP collector, DNS authorization and parser
One material reporter stopsTraffic change, reporter delay and intake filters
Message count collapsesSending volume/identity change or dropped rows
Unknown values appearSpecification/vendor change; preserve and update parser
Duplicates spikeIdempotency key and sender retries

Keep raw payloads long enough to replay after parser correction under privacy and storage policy.

Minimize data while keeping source accountability

Aggregate reports contain domains, IP addresses and operational metadata. Restrict source-level access, define retention and avoid joining recipient-level marketing data because aggregate reports do not require it. Reporting addresses and XML comments can contain unexpected text; escape all presentation.

Use pseudonymous incident identifiers in broad dashboards and keep raw source ownership in a controlled inventory. When sharing examples publicly, replace domains, IPs, report IDs and timestamps consistently. Do not upload proprietary reports to public analyzers without authorization.

Parser/analyst access should be logged. External report destinations need vendor security and deletion review.

Simulate policy effect before changing DNS

for each normalized row:
  effective_policy = resolve_policy(header_from, published_snapshot)
  aligned_pass = aligned_spf_pass OR aligned_dkim_pass
  proposed_action = aligned_pass ? "pass" : proposed_policy
  aggregate count by source_owner, reporter, stream, proposed_action

Simulation estimates report-row impact; it does not force receiver behavior. Include policy overrides, subdomain rules, pct limits and unknown sources separately. Review critical legitimate flows by owner and obtain final received samples.

Record the exact dataset/date range and proposed DNS artifact. Repeat immediately before release if sources changed. A month-old simulation is unsafe for fast-changing SaaS inventories.

Report authentication risk without hiding small sources

Show total represented messages, aligned pass, authorized misaligned, unknown/unauthorized, reporter coverage and enforcement disposition. Include counts beside percentages. Rank unknown sources by risk and owner status, not only volume. A ten-message payroll source can matter more than a large test stream.

Separate control health from policy strength: a domain at p=reject with broken ingestion is not better operated than a monitored domain correcting its last legitimate sources. Publish next action, owner and verification date for every material exception.

Detect selector and service drift inside passing domains

Track DKIM selector, signing domain and source together. A new selector may be a planned rotation, new vendor, regional route or unauthorized service. Verify it against the source inventory and final message. An old selector continuing after retirement can indicate delayed queues or credentials that were never disabled.

PatternAction
New selector on known sourceConfirm approved rotation and key strength
Known selector on unknown IPInvestigate key/credential use and vendor routing
Old selector persistsCheck queues, integrations and retirement plan
Aligned pass moves to vendor signatureEnsure customer identity was not lost

Selector inventory helps distinguish DNS/key incidents from audience and reputation problems.

DMARC reporting production checklist

  • Use RFC 9989 with RFC 9990 aggregate reporting.
  • Publish one valid policy record and external authorization.
  • Harden compressed XML ingestion.
  • Deduplicate and retain raw checksum/parser version.
  • Separate policy evaluation from authentication results.
  • Map every source, identity and selector to an owner.
  • Show counts, coverage, lag and unknowns.
  • Simulate policy changes on current data.
  • Test every legitimate route before enforcement.
  • Investigate small unknown sources rather than hiding them in pass rate.

Review after every ESP, DNS, selector, From-domain or acquisition change.

Worked security case: a valid vendor route is abused

Aggregate reports show a known aligned DKIM selector sending ten times its normal volume from the expected vendor range. DMARC passes, so a pass-only dashboard stays green. Internal campaign records contain no matching launch.

The team treats authentication as identity evidence, not authorization for the activity. It revokes the exposed API credential, holds the vendor account, preserves submission logs and suppresses attacker-generated queues. Provider/source volumes return to baseline in matured reports. A new alert compares authenticated source volume with approved campaign and credential activity.

This case proves why DMARC pass does not mean wanted, benign or authorized content. Report analysis must combine authentication with operational ownership and expected traffic.

Record standards and data review

Record the RFC versions, parser release, Public Suffix data version, report coverage window and responsible reviewer. Revalidate after standards, DNS, provider or service inventory changes.

Approval record

Retain the final policy approval, DNS artifact, owner, UTC release time and rollback condition with the reporting evidence.

Primary references

Continue learning

Related technical notes

A sending MTA discovers an MTA-STS DNS record, retrieves and caches an HTTPS policy, validates MX STARTTLS certificates and either delivers or queues for retryEmail Infrastructure & Authentication · Feb 15, 2026 · 13 min read

MTA-STS: Enforce TLS for Inbound Email Delivery

A staged implementation guide for MTA-STS policy hosting, MX matching, certificate validation, testing, enforcement, monitoring and incident recovery.

A recipient domain publishes a TLS-RPT DNS policy while sending MTAs aggregate TLS successes and failures into JSON reports, parsing, alerts and remediationEmail Infrastructure & Authentication · Feb 14, 2026 · 13 min read

TLS-RPT for Email: Publish, Read and Act on Reports

An operations guide to publishing TLS-RPT, ingesting aggregate JSON safely and converting transport-security reports into actionable evidence.

Technical review

Need this checked against your own sending system?

Share the domain, headers, bounces, provider warning, logs, or infrastructure symptom and NitWings will identify the practical next step.

Schedule a Technical Review
Advertisement