DNSVerdictAll toolsGuidesHow it works

DMARC record syntax errors and how to fix them

Published · Updated

A DMARC record with a syntax error is ignored or only partly applied, so receivers may treat your domain as having no DMARC policy at all. Open the DMARC checker, read the red line, and match it to the list below. The most frequent causes are a missing p= tag, something before v=DMARC1, a comma where a semicolon belongs, a bad rua address, and two DMARC records on _dmarc.

A correct record for comparison:

_dmarc.example.com.  3600  IN  TXT  "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"

Errors the checker reports

Checker messageCauseFix
Record must start with “v=DMARC1”Something precedes the version tag, it is misspelled, or the quotes were pasted into the valueMake v=DMARC1 the very first characters
Missing required “p=” policy tagPolicy omitted, or tags in the wrong orderAdd p=none, p=quarantine or p=reject right after v
Invalid policy “p=…”Typo such as p=rejected, p=quarentine, p=blockUse exactly none, quarantine or reject
Malformed tag ”…”A piece without =, often from a wrong separatorUse tag=value; tag=value
Report URI must be mailto:rua=dmarc@example.com without mailto:Write rua=mailto:dmarc@example.com
pct must be 0-100pct=105, pct=50%Use an integer without the percent sign
adkim / aspf must be r or sadkim=relaxedUse the single letter r or s
fo must be 0, 1, d, s or a colon listfo=1,dUse fo=1:d

The rules behind them

RFC 7489 §6.3 says the v tag is required and “MUST be the first tag in the list”; if its value does not match DMARC1 exactly, the entire record is ignored. The p tag follows it and is required for a policy record. A record that fails these rules does not just lose a tag: receivers discard the whole record (§6.6.3 step 2 discards records not starting with a v= tag that identifies DMARC).

Tags are separated by a semicolon with optional spaces around it (the ABNF in §6.4 allows whitespace on both sides). Commas, colons and plain spaces between tags do not work, although a comma is correct inside a tag whose value is a list, such as two rua addresses. A trailing semicolon is allowed.

Unknown tags are ignored (§6.3). So a misspelled optional tag such as rau= or pcts= produces no error from a receiver. It simply does nothing, and you lose reporting without noticing. Re-read tag names against the DMARC setup guide.

Report URIs

rua and ruf take a comma-separated list of URIs. Receivers must support mailto: (§6.2), so use it:

Wrong:  rua=dmarc@example.com
Wrong:  rua=mailto:dmarc@example.com; mailto:other@example.com
Right:  rua=mailto:dmarc@example.com,mailto:other@example.com

A size limit can follow an address after !, for example mailto:dmarc@example.com!10m (§6.2). Without the mailto: prefix, or with a space in the list, the address is unusable. If the address belongs to a different domain, the other domain must publish an authorization record (§7.1), or reports will not arrive; see How to set up a DMARC record.

Multiple records

If a query for _dmarc.example.com returns more than one DMARC record, discovery ends and DMARC is not applied to the message (§6.6.3 step 5). This usually happens when a second service asks you to “add” a DMARC record and you do so instead of editing the existing one. Fix it by deleting all but one and merging the tags, typically your rua and its p value. Use the DNS lookup for TXT at _dmarc.example.com to see what is actually published; some DNS panels show records you cannot see in the registrar’s own interface.

Common typos

FAQ

Which part of the record is checked first? The v=DMARC1 tag, because a mismatch there discards the entire record before any other tag is read.

The checker shows a warning, not an error. Is the record broken? No. Warnings, for example pct below 100, describe policy choices rather than invalid syntax.

I fixed the record but the checker still shows the old one. Resolvers cache the answer for the TTL. Wait for it to expire, or compare several resolvers with the DNS lookup.

Sources

Tools used

DMARC Record CheckerDNS Lookup