Reference
DMARC record tags
A DMARC record is a TXT record at `_dmarc` made of tag=value pairs separated by semicolons. RFC 7489 defines eleven tags: v and p are required, and sp, rua, ruf, adkim, aspf, fo, rf, ri and pct are optional with defined defaults. The tags that decide protection are p, sp and pct; rua is what makes a rollout observable. A revision of the specification, in draft form at the time of writing, removes pct, rf and ri and adds np, psd and t.
| Tag | Status | Values and default | Meaning | What the scan checks |
|---|---|---|---|---|
| v | Required, first | DMARC1 | Identifies the record as DMARC; a record not starting with it is not DMARC. | Only records starting with v=DMARC1 are read; two of them are reported as an error. |
| p | Required | none, quarantine or reject | The policy the domain owner requests for mail that fails DMARC. | Missing or invalid is an error; none is a warning, quarantine is reported for information, reject passes. |
| sp | Optional | none, quarantine or reject; defaults to the value of p | The policy for mail from subdomains. | Validated; its absence is reported with the policy subdomains inherit. |
| pct | Optional | Integer 0 to 100; default 100 | The percentage of failing messages the policy is applied to. | Must be an integer from 0 to 100; below 100 is a warning. |
| rua | Optional | Comma-separated URIs, usually mailto: | Where aggregate reports are sent. | Each address is validated; its absence is reported. |
| ruf | Optional | Comma-separated URIs, usually mailto: | Where message-specific failure reports are sent. | Each address is validated; mailbox local parts are masked in the report. |
| adkim | Optional | r (relaxed) or s (strict); default r | How closely the DKIM signing domain must match the visible From domain. | Must be r or s; the mode in force is reported. |
| aspf | Optional | r (relaxed) or s (strict); default r | How closely the SPF-authenticated domain must match the visible From domain. | Must be r or s; the mode in force is reported. |
| fo | Optional | 0, 1, d or s, colon-separated; default 0 | When failure reports should be generated: all mechanisms failed, any failed, DKIM failed, or SPF failed. | Kept in the record, not validated. |
| rf | Optional | Report format; default afrf | The format requested for failure reports. | Kept in the record, not validated. |
| ri | Optional | Seconds; default 86400 | The requested interval between aggregate reports. | Kept in the record, not validated. |
How the tags combine into a policy
`p` is the request itself. `none` asks receivers to take no action and only report; `quarantine` asks them to treat failing mail as suspicious, usually the spam folder; `reject` asks them to refuse it during the SMTP transaction.
`sp` applies the same choice to subdomains. Without it, subdomains inherit `p`, and a domain whose subdomains send no mail at all can publish `sp=reject` to shut down forgery of names nobody uses.
`pct` limits the policy to a share of failing mail. It exists for rollouts; outside one, anything below 100 leaves part of the forged traffic handled as if no policy existed.
`adkim` and `aspf` decide what counts as aligned. Relaxed, the default, accepts an authenticated domain that shares the organisational domain of the From address; strict requires the exact same name.
Syntax rules that break records
The record must start with `v=DMARC1`; a TXT record at `_dmarc` that does not is discarded. Tags are separated by semicolons, and whitespace around them is allowed.
A missing or invalid `p` does not make the record harmless: receivers apply no policy, except that when a valid `rua` is present they act as if `p=none` had been published, so reports still arrive.
Only one DMARC record may exist at `_dmarc`. With two, receivers behave as if there were none.
A reporting address on another domain than the one publishing the policy must be authorised by that other domain, through a TXT record under `_report._dmarc` on its side; without it, receivers do not send the reports.
An unknown tag is ignored rather than rejected, so a misspelled `sp` or `pct` changes nothing and says nothing.
What a scan validates, and the draft revision
The DMARC parser reads the first record starting with `v=DMARC1`, reports several as an error, and validates the values of `p`, `sp`, `adkim`, `aspf` and `pct` and the form of each `rua` and `ruf` address. `fo`, `rf` and `ri` are kept as published and not interpreted.
Separate checks grade what the values mean: `email.dmarc.policy` for `p`, `email.dmarc.subdomain` for `sp`, `email.dmarc.pct`, `email.dmarc.alignment`, `email.dmarc.rua` and `email.dmarc.ruf`, with `email.dmarc.present` and `email.dmarc.syntax` for the record itself.
The IETF DMARC working group has been revising the specification. Its draft, in revision 41 in April 2025, removes `pct`, `rf` and `ri`, adds `np` for non-existent subdomains, `psd` for public suffix domains and `t` for test mode, and is intended to obsolete RFC 7489 once approved. Receivers implement RFC 7489 until they adopt a published revision, so the table above describes the record they read today.
Frequently asked questions
- What is the minimum valid DMARC record?
- v=DMARC1; p=none published as a TXT record at _dmarc under the domain. It is valid and enforces nothing; adding rua is what makes it useful, because the aggregate reports show which sources send mail as the domain.
- Is pct still supported?
- It is part of RFC 7489, which receivers implement. The draft revision of DMARC removes it in favour of a test-mode tag, so a record relying on pct should be revisited once a revision is published and adopted.
- What happens if the sp tag is missing?
- Subdomains inherit the policy set by p. A domain with p=reject protects its subdomains too; a domain with p=none leaves them unprotected along with itself.
Sources
Related
VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.
Scan a website