HighAuthentication

DMARC record contains a syntax error

The DMARC record does not parse. Its tags are semicolon separated with a required version tag first, and a malformed tag, an unknown value or a missing v=DMARC1 prefix causes receivers to discard the record, which leaves the domain with no policy, not a partially applied one.

Check your own domainDMARC checker

What causes this

A DMARC record is a list of tag=value pairs separated by semicolons, and it must start with v=DMARC1 followed by a policy tag. Receivers that cannot parse the record generally discard it. Common causes are a missing semicolon, an unknown tag name, a policy value other than none, quarantine or reject, or a reporting address written without the mailto: prefix.

What it breaks

The policy may be ignored altogether, which silently removes the enforcement you believe is in place.

What the receiving server does

Receivers parse the record into tag and value pairs and validate them against the specification. The version tag must come first and must read exactly v=DMARC1. If it does not, the record is not DMARC and is ignored. If a required tag carries a value outside its permitted set (anything other than none, quarantine or reject for p, for example), the record is rejected as a whole. The domain then falls back to having no policy, so a syntax error in a p=reject record removes enforcement entirely while appearing, to anyone reading the zone, to be protected.

The errors that actually occur

DMARC syntax problems cluster around a handful of mistakes. The version tag is the most consequential, because getting it wrong means the record is not recognised as DMARC at all.

badv=DMARC1 p=rejecttags must be separated by semicolons, not spaces
badp=reject; v=DMARC1the version tag must come first
badv=DMARC1; p=quarantine; pct=101pct must be an integer from 0 to 100
badv=DMARC1; p=reject; rua=dmarc@example.comrua takes a URI, so it needs the mailto: scheme
goodv=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=100version first, semicolons between, valid values throughout

How to fix it

Fix the malformed tag so the record parses.

  1. Check the flagged tag against the DMARC specification.
  2. Confirm the record begins with v=DMARC1 and that p= is the second tag.
  3. Confirm every rua/ruf address is written as mailto:someone@example.com.
  4. Republish and re-check.

If you send with

Records edited by hand
Most DMARC records are typed once and never revisited, so an error introduced during an edit can survive for years. The rua tag is the usual casualty: it takes a URI and therefore requires the mailto: prefix, which is easy to omit because the value looks like an email address.
Values copied from articles
Older guidance sometimes shows tags that were proposed and never standardised, or uses a syntax that predates the final specification. If a tag is not one of v, p, sp, rua, ruf, pct, adkim, aspf, fo, rf or ri, check it before publishing.

Confirming the fix worked

  1. Confirm the record begins exactly v=DMARC1 with no preceding characters and no leading spaces.
  2. Confirm tags are separated by semicolons, and that values contain no stray spaces around the equals sign.
  3. Confirm every rua and ruf value carries the mailto: scheme.
  4. Re-run the check above, and confirm aggregate reports are arriving. A record that parses but is never reported on is worth a second look.

Common questions

Does a syntax error mean my policy is partially applied?
No. A record that fails to parse is discarded entirely and the domain is treated as having no DMARC policy. There is no partial application, which is why a broken p=reject record is more dangerous than an honest p=none.
Does the order of tags matter?
Only for the version tag, which must come first. The remaining tags may appear in any order, although keeping p immediately after v is conventional and makes records easier to read.
Is a trailing semicolon a problem?
No. A trailing semicolon after the last tag is tolerated by receivers and is common in published records.
Why does rua need mailto: in front of the address?
Because the tag is defined as taking a list of URIs rather than email addresses. The scheme is part of the syntax. Without it the value is not a valid URI and the record can be rejected.