On this page
  1. What receivers do with two DMARC records
  2. What happens after both are discarded
  3. How to merge two records into one
  4. Subdomain records are separate
  5. Check the result
  6. Sources

No: publish only one DMARC record at each name. If a lookup of _dmarc.example.com returns two records that start with the v tag set to DMARC1, RFC 9989 (opens in a new tab) has receivers discard both, so neither record's policy is used. Fix it by merging them: keep one policy, put every report address in one rua tag, and delete the other record. A subdomain can still have its own record, such as one at _dmarc.mail.example.com, which overrides the record it would otherwise inherit from its parent domain (Microsoft (opens in a new tab)).

What receivers do with two DMARC records

DMARC (opens in a new tab) (Domain-based Message Authentication, Reporting, and Conformance) is defined today by RFC 9989, which obsoletes RFC 7489. A domain's DMARC record is a DNS TXT record published at the name made by putting the label _dmarc in front of the domain (RFC 9989 section 4.1 (opens in a new tab)). Receivers start by querying that name for the author domain (section 4.10.1 (opens in a new tab)), the domain taken from the message's From header (section 3.2.2 (opens in a new tab)).

That query can return several TXT records, and section 4.10 (opens in a new tab) sorts them in two steps:

  1. Records that don't start with a v tag identifying the current DMARC version are discarded. A TXT record at _dmarc that isn't a DMARC record is dropped here and doesn't count.
  2. "If multiple DMARC Policy Records are returned for a single target, they are all discarded."

To count as a DMARC record, the v tag must come first and its value must be exactly DMARC1; otherwise the whole record is ignored (section 4.7 (opens in a new tab)). One record split over several strings is still one record: a TXT record can hold several character strings, and receivers join them in order and read the result as a single string (section 4.5 (opens in a new tab)).

Microsoft's DMARC troubleshooting quick-reference table (opens in a new tab) lists dmarc=temperror or dmarc=permerror results with the likely cause "DNS issues retrieving DMARC record (timeout, syntax error)". Its resolution is to fix DNS syntax errors and make sure only one _dmarc TXT record exists.

Check your domain now

See the SPF, DKIM and DMARC records your domain publishes and what to fix first. Free, no account needed.

What happens after both are discarded

Discarding the duplicates (RFC 9989 section 4.10 (opens in a new tab)) leaves no valid record at the first name queried. When the first query finds no valid record, receivers continue with a DNS tree walk toward the author domain's organizational domain, starting at its immediate parent domain (for domains of eight or fewer labels) (RFC 9989 section 4.10.1 (opens in a new tab)). For duplicates at _dmarc.mail.example.com, the walk starts at the immediate parent, example.com. If the tree walk finds no DMARC record either, receivers must not apply DMARC to the message.

The older standard, RFC 7489 (opens in a new tab), also discarded records without a current v tag, but stopped earlier: if more than one record remained, policy discovery terminated and DMARC was not applied to the message. Under either standard, a policy published twice at one name is not used. RFC 9989 vs RFC 7489 covers the DNS tree walk and the other changes.

How to merge two records into one

Here is a typical pair of duplicates:

Name TXT value
_dmarc.example.com v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com
_dmarc.example.com v=DMARC1; p=none; rua=mailto:reports@example.net
  1. List what each record asks for. Look up the name with nslookup -type=TXT _dmarc.example.com, the command Microsoft (opens in a new tab) uses to validate DMARC record syntax, with your domain in place of example.com. Note the p value and report addresses in every record that starts with the v tag set to DMARC1.
  2. Pick one policy. Once a single valid record remains, receivers apply it, with the policy taken from its p tag (RFC 9989 section 4.10.1 (opens in a new tab)). A message passes DMARC only when an authenticated identifier aligns with the author domain (section 5.3.5 (opens in a new tab)), and those identifiers are the SPF domain and the DKIM signing domain (section 4.3 (opens in a new tab)). Keep quarantine or reject only when your reports show your real senders pass DMARC, with aligned SPF or DKIM; moving too early can block legitimate email (check). Otherwise keep p=none. How to set up DMARC walks through that order.
  3. Put every report address in one rua tag. The rua tag takes a comma-separated list of reporting URIs (RFC 9989 section 4.7 (opens in a new tab)), and a report should be sent to each URI listed (section 4.6 (opens in a new tab)). Separate the addresses with a comma and put mailto: before each one (Google Workspace (opens in a new tab)).
  4. Check report addresses on another domain. When a rua address sits on a different organizational domain from the record, like reports@example.net here, receivers verify it first (RFC 9990 section 4 (opens in a new tab)). They query a TXT record at the address's host with _report._dmarc and then the policy's domain prepended: example.com._report._dmarc.example.net. A single reply containing the v tag set to DMARC1 confirms the arrangement; if nothing confirms it, receivers ignore that address. The report consumer publishes that record if it wants reports for other domains.
  5. Keep the other tags you need. If either record set sp, adkim or aspf, carry the value you want into the merged record. DMARC record tags covers each tag and its default.
  6. Publish one record and delete the other. Edit one record to the merged value and remove the second. Google's setup page notes that some domain hosts automatically add the domain name, so check the saved name is _dmarc for your domain.

If your reports show your senders pass DMARC with aligned SPF or DKIM, the merged record for the pair above is:

v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com,mailto:reports@example.net

If they don't yet, publish the same record with p=none. The DMARC record generator builds the record one step at a time and takes report addresses one per line.

Subdomain records are separate

A record at _dmarc.mail.example.com sits at a different name from _dmarc.example.com, so the two are not duplicates. RFC 9989's own example publishes a record at _dmarc.test.example.com that applies only to that subdomain, and not at _dmarc.example.com (appendix B.2.5 (opens in a new tab)). The same example sends aggregate reports from that one record to two mailboxes: one within the organizational domain and one at a report consumer the domain owner authorized. The duplicate rule applies at each name on its own: two DMARC records at _dmarc.mail.example.com are all discarded too (section 4.10 (opens in a new tab)).

A subdomain doesn't need a record of its own. The DMARC TXT record for a domain covers all subdomains, including nonexistent ones, that don't have their own, and a separate record in the subdomain overrides that inheritance (Microsoft (opens in a new tab)). No DMARC record found covers checking subdomain inheritance.

Two ways to give subdomains a different policy:

  • sp on the parent record. The sp tag sets the policy for existing subdomains, not for the domain itself; when neither sp nor np applies, subdomains get the p policy (RFC 9989 section 4.7 (opens in a new tab)). sp is ignored in a record published on a subdomain of the organizational domain, because of how policy discovery works.
  • A record of the subdomain's own. When the record found is the one for the author domain itself, the policy comes from its p tag (section 4.10.1 (opens in a new tab)).

For example:

Name TXT value
_dmarc.example.com v=DMARC1; p=reject; sp=quarantine; rua=mailto:dmarc-reports@example.com
_dmarc.mail.example.com v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com

Here example.com gets reject, other existing subdomains get quarantine from sp, and mail.example.com gets none from its own record.

Check the result

DemiSignal's DMARC check reads the public DNS record at your domain's _dmarc name (_dmarc.example.com for example.com), the same one every receiver reads, and shows the policy receivers apply and where reports go. A change shows once your DNS provider publishes the new record and the old one's TTL runs out; run the check again to see what receivers see now. The full SPF, DKIM and DMARC check only reads the public DNS records of the domain you enter, and needs no account.

Sources

Tools for this

Frequently asked questions

Can you have multiple DMARC records?

Not at the same name. If a lookup of a domain's _dmarc name returns more than one DMARC record, RFC 9989 has receivers discard all of them. A subdomain can still have its own record at its own _dmarc name.

How do I send DMARC reports to two addresses?

List both in one rua tag, separated by a comma, with mailto: before each address. Receivers ignore an address on another organizational domain unless the report consumer publishes a TXT record confirming it.

Does every extra TXT record at _dmarc count as a duplicate?

No. Receivers first discard records that do not start with a v tag for the current DMARC version, and a single TXT record split into several strings is joined and read as one record.

Check your domain now

See the SPF, DKIM and DMARC records your domain publishes and what to fix first. Free, no account needed.