This page contains a technical reference for how DMARCwise processes DMARC reports, especially when it comes to normalization and correction of invalid reports. It may in some cases help explain discrepancies you may see in the dashboard compared to the original reports.

Once received as an attachment to an email message, a DMARC report is parsed and passed through a validator.

The validator is typically lax and forgives many issues that would be unacceptable according to the DMARC specification. Some fields in the XML reports are however validated more strictly, otherwise the report would be very hard to use in practice. This includes for example the policy fields, which must contain a valid policy name.

Although blatantly invalid reports are rare, when one such report is received it is not imported and is retained for manual review.

Corrections

To prevent reports from being discarded for minor reasons, we apply corrections, which fall into three categories:

  • Normalization: a field is cleaned up with the aim of improving compatibility or making the data more usable. Examples include lowercasing values, removing invalid punctuation, accepting typos. These are high-confidence harmless corrections.
  • Recovered: a field contains an invalid value that violates the DMARC specification, but the intent is clear enough that we can replace it with a valid value. Our judgement is that replacing or inferring the intended value is more useful than discarding the report.
  • Discarded: an individual unusable or invalid item is removed so the rest of the report can still be processed. An example is discarding a DKIM auth result which contains no data. These items are usually the result of bugs in the software that generated the report.

These corrections are based on bad reports we’ve seen in the past and are updated when new invalid reports come through.

When you browse a report in DMARCwise, you already see the normalized/corrected data. When a correction was applied, a badge is shown and clicking on it lets you see how the data was modified.

DMARC report corrections badge in report page

You can also always see the original unprocessed report in XML format.

Our implementation of the parsing, correction and validation of DMARC reports is thoroughly tested with automated tests.

List of corrections

The tables below list the corrections we currently apply to new reports we receive, grouped by category. Each row references the original DMARC XML element (using the path from the report’s <feedback> root) and explains what happens to it. Note that these rules change over time, so you may see different corrections in older reports.

Normalization

XML elementCorrection
policy_published/pSurrounding semicolons are trimmed, e.g. reject; becomes reject.
policy_published/pAn empty value is treated as missing (as if the p tag was absent).
policy_published/spSurrounding semicolons are trimmed.
policy_published/spAn empty value is treated as missing.
policy_published/pctA trailing percent sign is trimmed, e.g. 100% becomes 100.
policy_published/pctAn empty value is treated as missing.
policy_published/aspfAn empty value is treated as missing.
policy_published/adkimAn empty value is treated as missing.
record/identitiesThe misspelled identities element is renamed to the correct identifiers.
record/auth_results/spf/resultLowercased.
record/auth_results/dkim/domainLowercased.
record/auth_results/dkim/selectorLowercased.
record/auth_results/dkim/resultLowercased.

Recovered

XML elementCorrection
policy_published/pThe invalid value unknown is treated as missing (as if the p tag was absent).
policy_published/spThe invalid value unknown is treated as missing.
policy_published/aspfThe invalid value unknown is treated as missing.
policy_published/adkimThe invalid value unknown is treated as missing.
record/identifiers/header_fromWhen empty or missing, it is filled with the value of envelope_from.
record/row/policy_evaluated/dkimA non-pass DKIM result (none, neutral, temperror, permerror) is replaced with fail. The alignment result can only be pass or fail, and alignment cannot exist without a DKIM pass, so any recognized non-pass result is treated as an alignment failure.
record/row/policy_evaluated/spfA non-pass SPF result (none, neutral, softfail, temperror, permerror) is replaced with fail. The alignment result can only be pass or fail, and alignment cannot exist without an SPF pass, so any recognized non-pass result is treated as an alignment failure.

Discarded

XML elementCorrection
recordWhen the report contains a single record row whose count is 0, the record is discarded but the report is kept. These records are typically completely empty and would fail validation.
record/auth_results/spfDiscarded when its result is empty.
record/auth_results/spfDiscarded when its domain is empty.
record/auth_results/dkimDiscarded when its result is none: a result of none means the message was not signed, so it makes little sense to present it as a DKIM signature.
record/auth_results/dkimDiscarded when its result is empty.
record/auth_results/dkimDiscarded when its domain is empty.