Domain-based Message Authentication, Reporting and Conformance (DMARC) reports

Domain-based Message Authentication, Reporting and Conformance (DMARC) allows domain owners to communicate to email receivers what they should do with messages that fail to authenticate using Sender Policy Framework (SPF) and/or DomainKeys Identified Mail (DKIM). You can also employ DMARC to request reporting of authentication and disposition results of received mail. The DMARC policy for example.com must be published in DNS TXT records for _dmarc.example.com.

Example DMARC DNS record for the example.com domain

TXT "v=DMARC1; p=quarantine; rua=mailto:example@dmarc.report-uri.com,mailto:security@example.com; ruf=mailto:security@example.com"

The email address in rua and ruf should be the same as the domain where the DMARC policy was found at, which is the case for the failure reports in the example above. If it's not the case, as in the rua example, the mail receiver should check whether it can send the example.com report to dmarc.report-uri.com host by querying example.com._report._dmarc.dmarc.report-uri.com DNS TXT records and checking for one that starts with v=DMARC1. The dmarc.report-uri.com host can signal that it is willing to receive reports for any domain by publishing a wildcard record *._report._dmarc.dmarc.report-uri.com. These checks are the reason you cannot send your DMARC reports to Gmail and possibly other free email services because they don't publish the required DNS records.

The canhas.report domain has a DMARC DNS record similar to the example above and michalspacek.cz publishes the required DNS record for the external reporting to succeed.

Example DMARC report

This is an aggregated report for example.com sent by Google, with two actual reports, one that has passed authentication and the other has failed both DKIM and SPF checks:

<?xml version="1.0"?>
<feedback>
  <report_metadata>
    <org_name>google.com</org_name>
    <email>noreply-dmarc-support@google.com</email>
    <extra_contact_info>https://support.google.com/a/answer/2466580</extra_contact_info>
    <report_id>94914750191783696133</report_id>
    <date_range>
      <begin>1589673600</begin>
      <end>1589759999</end>
    </date_range>
  </report_metadata>
  <policy_published>
    <domain>example.com</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>quarantine</p>
    <sp>quarantine</sp>
    <pct>100</pct>
  </policy_published>
  <record>
    <row>
      <source_ip>192.0.2.1</source_ip>
      <count>1</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>pass</dkim>
        <spf>pass</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>example.com</header_from>
    </identifiers>
    <auth_results>
      <dkim>
        <domain>example.com</domain>
        <result>pass</result>
        <selector>google</selector>
      </dkim>
      <spf>
        <domain>example.com</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
  <record>
    <row>
      <source_ip>198.51.100.123</source_ip>
      <count>1</count>
      <policy_evaluated>
        <disposition>quarantine</disposition>
        <dkim>fail</dkim>
        <spf>fail</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>example.com</header_from>
    </identifiers>
    <auth_results>
      <spf>
        <domain>example.com</domain>
        <scope>mfrom</scope>
        <result>softfail</result>
      </spf>
    </auth_results>
  </record>
</feedback>

Related specs & documents