Why validate DMARC syntax before publishing?
A malformed DMARC record is silently ignored by Gmail, Outlook, Yahoo and all receiving servers. No alert is raised. Your emails remain unprotected against spoofing and phishing.
The validator reads your record before DNS publication, checks each tag and verifies the report URIs. You fix errors immediately, without waiting 24 to 48 hours for propagation only to discover that a detail prevents the policy from being applied.
DMARC tags according to RFC 9989
RFC 9989 defines every tag allowed in a DMARC record. The validator checks the name, position and value of each tag.
| Tag | Role | Example |
|---|---|---|
| v | Protocol version, always first | v=DMARC1 |
| p | Policy applied to the apex domain | p=quarantine |
| sp | Policy applied to subdomains | sp=reject |
| np | Policy for nonexistent subdomains | none / quarantine / reject |
| t | RFC 9989 testing mode | y / n |
| adkim | DKIM alignment mode, r (relaxed) or s (strict) | adkim=s |
| aspf | SPF alignment mode, r or s | aspf=r |
| pct | Historical/deprecated tag, range 0-100 | Omit |
| rua | Aggregate report destinations (mailto URI) | rua=mailto:dmarc@captaindns.com |
| ruf | Forensic report destinations (mailto URI) | ruf=mailto:forensic@captaindns.com |
| fo | Forensic report generation options | fo=1 |
Tags v and p are mandatory. When omitted, adkim and aspf default to r. Omitting the now-historical pct tag is recommended.
Before-and-after correction examples
The validator flags every syntax error with its position. Here are three common cases seen on published records.
Malformed rua URI:
- v=DMARC1; p=reject; rua=reports@captaindns.com
+ v=DMARC1; p=reject; rua=mailto:reports@captaindns.com
The mailto: prefix is required by RFC 9989.
Invalid p policy:
- v=DMARC1; p=monitor; rua=mailto:dmarc@captaindns.com
+ v=DMARC1; p=none; rua=mailto:dmarc@captaindns.com
Only none, quarantine and reject are accepted.
pct out of range:
- v=DMARC1; p=quarantine; pct=150; rua=mailto:dmarc@captaindns.com
+ v=DMARC1; p=quarantine; rua=mailto:dmarc@captaindns.com
The pct value is outside the 0-100 range; omit pct to fix it.
Common validator diagnostics
The validator returns a short code for each anomaly detected. The codes below are the most frequent.
| Code | Cause | Action |
|---|---|---|
| missing_version_tag | Tag v=DMARC1 missing | Add v=DMARC1 as the first tag |
| unsupported_version | Value of v= other than DMARC1 | Replace with v=DMARC1 |
| missing_policy | Tag p= missing | Add p=none, p=quarantine or p=reject |
| invalid_policy | Value of p= outside none/quarantine/reject | Correct the value |
| invalid_subdomain_policy | Value of sp= invalid | Use none, quarantine or reject |
| invalid_alignment | adkim= or aspf= value other than r/s | Set to r or s |
| invalid_percent | pct= outside 0-100 range | Use an integer between 0 and 100 |
| invalid_rua_uri | Malformed rua URI | Use mailto:address@domain |
| invalid_ruf_uri | Malformed ruf URI | Use mailto:address@domain |
| invalid_failure_option | Unknown fo= value | Use 0, 1, d or s |
| duplicate_tag | Tag declared twice | Keep a single occurrence |
| unknown_tag | Unrecognized tag name | Check spelling against RFC 9989 |
| np_absent | np absent | Check inheritance from sp or p |
| deprecated_pct | Historical pct present | Remove pct |
| testing_mode_active | t=y active | Score reflects effective enforcement |
| migrate_to_dmarcbis | Historical tags found | Use the migration tool for record hygiene |
| record_trailing_quote | TXT string ends with a quote | Remove the trailing quote |
Warning-level codes (policy_none, pct_less_than_100, subdomain_policy_none) flag a valid configuration that needs review. pct_less_than_100 concerns a historical tag: under RFC 9989, omit pct rather than setting pct=100.
FAQ - Frequently asked questions
What deployment progression should I follow for the p= policy?
Always start with p=none to observe traffic through aggregate (rua) reports. Once SPF and DKIM are aligned across all your legitimate sources, move to p=quarantine, then p=reject. Avoid jumping straight to p=reject: the observation-phase rua reports almost always reveal forgotten legitimate streams.
Should I configure ruf as well as rua?
Not at the start. Aggregate rua reports (daily) are essential for steering your rollout. Forensic ruf reports (per failing message) generate significant volume and may contain personal data. Enable them only if you have an analysis pipeline and a legal opinion on collecting this data.
Should I configure the sp= tag on subdomains?
By default, subdomains inherit the p policy. Configure sp= only if the subdomain policy must differ from the apex. Verify that SPF and DKIM are aligned on each sending subdomain before tightening sp=.
Does the validator apply DMARCbis rules?
DMARCbis was published in May 2026 as RFC 9989, RFC 9990, and RFC 9991. RFC 9989 obsoletes RFC 7489; v=DMARC1 is unchanged. The DMARCbis Checker explains DNS tree walk behavior, and the DMARCbis Migration Tool removes historical tags.
Complementary tools
| Tool | Purpose |
|---|---|
| DMARC Checker | Verify publication and resolve the DMARC record from DNS |
| DMARC Generator | Create a spec-compliant DMARC record |
| SPF Validator | Validate the SPF syntax for your domain |
| DKIM Validator | Validate the syntax of a DKIM key |
| DMARCbis Migration | Migrate a DMARC record to the new standard |
| DMARC Monitoring | Receive and analyze your aggregate DMARC reports automatically |