Without DMARC, anyone can send email claiming to be from your domain. Your company name, your logo, your letterhead, with no way for recipients to tell the real thing from a fake.
A DMARC record is a DNS TXT record that tells mail servers how to verify email from your domain and what to do when verification fails. You publish it once, and email providers like Gmail, Yahoo, and Microsoft read it before delivering messages that claim to be from your domain.
RFC 9989 is the current Standards Track document that defines DMARC policy records. It obsoletes both RFC 7489 (the original DMARC specification) and RFC 9091 (the experimental PSD DMARC extension), while preserving the v=DMARC1 version string.
What you will learn
Your first DMARC record
A DMARC record is a single line of text you add to your domain's DNS. It always starts with v=DMARC1 (the version) followed by p= (your policy). Everything else is optional.
Here is the simplest useful DMARC record. It tells email providers: "I am not enforcing anything yet, but please send me daily reports so I can see who is sending email as my domain."
Add this as a TXT record at _dmarc.example.com (replace with your domain).
That is it. Three tags, one DNS record, and you are already getting visibility into your email authentication. The reports arrive as XML files, typically once a day from each provider that processes your email.
Which DMARC record should I publish?
The right record depends on two things: whether the domain sends email at all, and whether you have watched your reports long enough to trust enforcement. Walk this once and you land on the correct starting record.
Special cases. A domain that sends from a subdomain only (for example billing.example.com) can publish p=reject on the organizational domain but sp=none until the subdomain reports are clean. Registry and hosting operators that manage many child domains use the psd tag instead of this flow.
Ready-to-use records for common setups
Find your situation below, copy the record, and replace the email address with yours.
Just starting out (monitoring only)
You want to see what is happening before making any changes. Good choice.
Gmail or Microsoft 365 + a marketing tool (Mailchimp, HubSpot, etc.)
You send email from your inbox and through a marketing platform. Start with monitoring, then move to quarantine once your reports show clean results.
adkim=r and aspf=r use "relaxed" alignment. This means mail.example.com and example.com are treated as the same organization. This is what you want when third-party services send on your behalf.
Full protection (after 2-4 weeks of clean monitoring)
You have reviewed your reports and confirmed that all legitimate senders pass SPF and DKIM. Time to tell providers: reject anything that fails.
p=reject tells providers to block fraudulent email. sp=reject does the same for subdomains. adkim=s and aspf=s switch to "strict" alignment for maximum security.
Enterprise with external DMARC reporting service
You use a service like DMARCTrust to collect and analyze your reports. You can send reports to multiple addresses.
Reports go to both your internal inbox and your DMARC reporting service. The external service must authorize your domain via a DNS record (explained below).
Not sure which record fits? Use our free DMARC generator to build a record step by step, or check your existing record to see what you have today.
A real DMARC record, tag by tag
Before the full reference, here is how to read any DMARC record. Below is a fully-loaded record for an enforcing domain. Each tag does one specific job, in a predictable order.
Published as a TXT record at _dmarc.example.com.
| Tag | In plain language |
|---|---|
| v=DMARC1 | This is a DMARC record. It must come first, with exactly this casing. |
| p=reject | For example.com itself, ask receivers to reject mail that fails. |
| sp=reject | Apply the same policy to subdomains that exist, like mail.example.com or shop.example.com. |
| np=reject | And to subdomains that do not exist in DNS at all, which blocks spoofing of names you never created. |
| rua=mailto:… | Send the daily summary reports to my inbox and to my reporting service. |
| adkim=r; aspf=r | Use relaxed alignment: a subdomain counts as the same organization as example.com. |
| t=n | Not in test mode. Enforce the policy for real, which is the default. |
Read every DMARC record in that order: the version, then what to do with failing mail (p, sp, np), then where to send reports (rua), then how strictly to match the sender to your domain (adkim, aspf), and finally the test flag (t). The rest of this guide explains each tag in full.
Every DMARC tag explained
RFC 9989 defines the active DMARC DNS tags. It keeps the original deployment model from RFC 7489, adds np, psd, and t, and moves pct, rf, and ri to historic status. Here is what each tag does, when you need it, and how to use it. For a full read of what changed in RFC 9989/9990/9991, see our RFC 9989/9990/9991 explainer.
| Tag | What it does | Example value | Default | Status |
|---|---|---|---|---|
| v | Identifies this as a DMARC record | DMARC1 | Required first | Mandatory |
| p | What to do with failing email | none | quarantine | reject | none if omitted | Recommended |
| sp | Policy for subdomains | none | quarantine | reject | Inherits p | Optional |
| adkim | How strictly to check DKIM alignment | r (relaxed) | s (strict) | r | Optional |
| aspf | How strictly to check SPF alignment | r (relaxed) | s (strict) | r | Optional |
| rua | Where to send daily summary reports | mailto:[email protected] | None | Optional |
| ruf | Where to send per-failure reports | mailto:[email protected] | None | Optional |
| fo | When to trigger failure reports | 0 | 1 | d | s | 0 | Optional |
| pct | Percentage of email to apply policy to | 0-100 | 100 | Removed in RFC 9989 |
| rf | Format for failure reports | afrf | afrf | Removed in RFC 9989 |
| ri | How often to send aggregate reports | 86400 (seconds) | 86400 | Removed in RFC 9989 |
| np | Policy for non-existent subdomains | none | quarantine | reject | Inherits sp/p | New in RFC 9989 |
| t | Test mode flag (downgrade policy by one level) | y | n | n | New in RFC 9989 |
| psd | Flag identifying the domain as a Public Suffix Domain | y | n | u | u | New in RFC 9989 |
Tags removed in RFC 9989 (May 2026). The pct, rf, and ri tags are defined in RFC 7489 but have been removed by RFC 9989. Existing records that use them keep working (RFC 9989 §4.7 says unknown tags MUST be ignored). Leave them out of new records.
Tags added in RFC 9989. np lets you set a different policy for subdomains that do not exist in DNS, which is useful for blocking spoofing of names you never published. t replaces the most useful part of pct: t=y asks receivers to apply the next-lower policy (e.g., quarantine instead of reject) while you test. psd is for Public Suffix Operators (country-code registries, gTLDs, organizations managing TLDs like .bank); end-user domain owners almost never set it.
The core tags: v and p
Every DMARC record must start with v=DMARC1. The p tag is strongly recommended, but RFC 9989 says an otherwise valid record without p is treated as if it published p=none.
v = version
Always v=DMARC1. No other value exists. It tells email servers that this DNS record is a DMARC policy, not some other TXT record. Use this exact casing for the version value.
p = policy
This is the core decision. You are telling every email provider in the world what to do when someone sends an email that claims to be from your domain but fails authentication. Three choices:
| Value | What happens | When to use |
|---|---|---|
| none | Deliver the email normally. Just send me reports. | You are starting out and want to observe before enforcing. |
| quarantine | Flag the email as suspicious. Usually goes to spam. | You are fairly confident in your setup but want a safety net. |
| reject | Ask receivers to reject failing mail. RFC 9989 (sections 7.4 and 8) still requires receivers not to reject solely on this tag, but to combine it with local analysis. | You have verified legitimate senders and the domain is appropriate for reject enforcement. |
Start with p=none. Jumping straight to p=reject without monitoring first is the most common mistake. Because RFC 9989 directs receivers not to reject solely on p=reject (sections 7.4 and 8), p=quarantine is often the safer end state for general-purpose mailbox domains unless you have a clear reason to reject.
Optional tags: fine-tuning your policy
sp = subdomain policy
Your main policy (p=) covers your root domain (example.com). But what about mail.example.com, shop.example.com, or any other subdomain? By default, subdomains inherit whatever policy you set for the parent. The sp tag lets you override that.
Common scenario: You want to protect subdomains that do not send email. Attackers love these because they are often unmonitored.
If you omit sp, subdomains inherit the p value.
What "alignment" means
The next two tags, adkim and aspf, both control alignment. Alignment is the check at the heart of DMARC: it is not enough for SPF or DKIM to pass, the domain they authenticate has to match the domain a human sees in the From header.
adkim = DKIM alignment mode
When an email arrives with a DKIM signature, the receiving server checks whether the signing domain matches the From address. The adkim tag controls how strict that match needs to be.
Relaxed allows subdomains to match the organizational domain. Strict requires an exact domain match.
| Mode | From address | DKIM d= domain | Result |
|---|---|---|---|
| r (relaxed) | [email protected] | example.com | Pass Same organization |
| s (strict) | [email protected] | example.com | Fail Domains do not match exactly |
| s (strict) | [email protected] | mail.example.com | Pass Exact match |
Default is relaxed. Use strict only when you have full control over all signing domains. If you use third-party services (Mailchimp, SendGrid, etc.), keep relaxed or make sure they sign with your exact domain. For how DKIM signing domains work in full, see the DKIM overview.
aspf = SPF alignment mode
Same concept as adkim, but for SPF. It checks whether the domain that passed SPF matches the From address.
| Mode | From address | SPF-validated domain | Result |
|---|---|---|---|
| r (relaxed) | [email protected] | example.com | Pass Same organization |
| s (strict) | [email protected] | example.com | Fail Domains do not match exactly |
| s (strict) | [email protected] | mail.example.com | Pass Exact match |
Default is relaxed. Same guidance as adkim. Start relaxed, tighten later if needed. For a deep dive on alignment, see our guide on DMARC aspf and adkim tags or learn how DMARC, SPF, and DKIM alignment works together.
Organizational Domain and the DNS tree walk
Both adkim and aspf rely on the concept of an "organizational domain." RFC 7489 used the Public Suffix List to draw that boundary. RFC 9989 §4.10 (May 2026) replaced it with a "DNS Tree Walk", but for ordinary domains both land on the same boundary:
The tree walk works one DNS label at a time. To find the Organizational Domain for a sender like [email protected], a receiver queries _dmarc at each level, walking up until it finds a record:
The walk stops at the first record it finds. To stop a malicious sender from forcing thousands of lookups with a deeply nested name, RFC 9989 section 4.10 caps the walk at eight DNS queries, even for names with more than eight labels. That is the main practical difference from RFC 7489, which guessed the boundary from the Public Suffix List instead. A hosting provider can set psd=y so each customer domain becomes its own Organizational Domain during the walk.
Reporting tags: seeing what is happening
Without reporting tags, you have a policy with no visibility into what it is doing. Two types of reports exist:
rua = aggregate reports (the daily summary)
Every 24 hours, email providers send you an XML file summarizing: who sent email claiming to be your domain, from which IP addresses, and whether those emails passed or failed SPF and DKIM.
These reports contain statistics, not actual emails. A typical entry looks like: "IP 203.0.113.42 sent 1,200 emails as your domain; 1,180 passed DKIM, 20 failed SPF."
You get roughly one aggregate report per day from each receiver that processed your mail, not one per message. A small business typically sees a handful of XML files a day, each a few kilobytes. Volume scales with the number of distinct receiving providers, not with how much you send.
RFC 7489 allowed report URI size suffixes such as !50m. RFC 9989 made that suffix obsolete. Existing records may still contain it, but new records should omit it.
Privacy note: Aggregate reports are metadata, not message content. They still include sending infrastructure details such as source IP addresses, so handle and retain them like operational security data.
Sending reports to a different domain
If your DMARC record points rua to an address outside your domain (like a reporting service), the receiving domain must give permission. Otherwise, anyone could flood a victim's inbox with millions of DMARC reports from random domains.
The receiving domain grants permission by publishing a DNS TXT record:
Without this permission record, email providers silently discard the reports. If you use a DMARC reporting service, they handle this setup for you.
Once reports start arriving, DMARCTrust files each one in the Reports module, with filters by date, source IP, and sender organisation.
Read an aggregate report back to your tags
The payoff of rua is being able to read a report and tell whether a sender is healthy. Here is one record from an aggregate report, trimmed to the parts that matter:
| What the report says | What it means |
|---|---|
| disposition=none | Your policy is p=none, so the receiver delivered the mail normally. At p=reject this row would read reject. |
| policy_evaluated dkim=pass | DKIM aligned: auth_results shows DKIM signed by example.com, which matches the From domain. One aligned mechanism is enough to pass DMARC. |
| policy_evaluated spf=fail | SPF did not align: auth_results shows SPF authenticated mail.marketing-tool.com, not example.com. Raw SPF passed, but it authenticated the wrong domain for alignment. |
| count=1180 | 1,180 messages from this source in the reporting window, all with the same result. |
The verdict: this is a healthy source. The mail passes DMARC on aligned DKIM, so the SPF misalignment is harmless and there is nothing to fix. Mistaking raw SPF (in auth_results) for aligned SPF (in policy_evaluated) is the single most common reason people think a working sender is broken.
ruf = failure reports (per-failure detail)
While rua gives you the summary, ruf tries to give you the details: the actual headers (and sometimes body) of individual emails that failed authentication.
In practice, ruf is rarely useful. Failure reports can expose real user data, so most mail receivers refuse to send them or heavily redact them. Most DMARC deployments work perfectly with rua only.
The syntax is identical to rua:
When failure report samples do arrive, DMARCTrust groups them in the Failure reports module with filters by failure type, date, and sender domain.
fo = failure reporting options
The fo tag controls when failure reports (ruf) are triggered. Since most providers do not send failure reports anyway, this tag has limited practical value. Each value triggers reports at a different threshold:
| Value | Trigger condition | Report volume |
|---|---|---|
| 0 | Both SPF and DKIM fail (default) | Lowest. Only total failures. |
| 1 | Either SPF or DKIM fails | Highest. Any single failure triggers a report. |
| d | DKIM fails (regardless of SPF) | Moderate. DKIM-specific issues only. |
| s | SPF fails (regardless of DKIM) | Moderate. SPF-specific issues only. |
You can combine options with a colon: fo=1:d. In practice, if you use ruf at all, fo=1 gives you the most visibility.
New in RFC 9989: np, t, and psd
RFC 9989 added three tags to core DMARC. Two are useful to ordinary domain owners (np and t); the third (psd) is for the operators of public suffixes.
np = non-existent subdomain policy
The np tag sets a policy for subdomains that do not exist in DNS at all. It is the cheapest win in DMARC: because no legitimate mail ever comes from a name you never created, you can publish np=reject even while the parent domain is still at p=none. This blocks attackers who spoof invented names like support.example.com that you never published.
When a receiver decides which policy to apply, it resolves in this order:
| Incoming From domain | Exists in DNS? | Policy applied |
|---|---|---|
| example.com | Organizational domain | p |
| mail.example.com | Yes (has records) |
sp if present, else p
|
| ghost.example.com | No |
np if present, else sp, else p
|
Valid values are none, quarantine, and reject, the same as p.
t = test mode
The t tag (default t=n) is the RFC 9989 replacement for the most useful part of the old pct tag. With t=y, receivers apply the policy one level below what you published: a p=reject record is treated as quarantine, and a p=quarantine record is treated as none. It lets you publish your intended enforcement posture while still testing, then drop t=y to go live. It has no effect on a policy that is already none.
psd = public suffix domain flag
The psd tag (values y, n, u; default u) is for operators of public suffixes: country-code registries, gTLDs, and organisations running a name like .bank under which many independent organisations register. It folds the old experimental PSD DMARC (RFC 9091) into the core spec. End-user domain owners almost never set it; leave it at the default unless you operate a registry.
Tags removed in RFC 9989: skip these in new records
Three tags from RFC 7489 were removed when RFC 9989 was published in May 2026. The current standard no longer defines them for new records.
pct (percentage)
Originally let you apply your policy to only a percentage of failing email (e.g., pct=25 would quarantine 25% and let the rest through). In practice, only pct=0 and pct=100 worked reliably. RFC 9989 replaces it with the t=y test mode flag, which asks receivers to apply the next-lower policy while you test.
ri (report interval)
Supposed to control how often aggregate reports are sent (default: 86400 seconds = 24 hours). In practice, receivers send reports on their own cadence and do not treat this as a precise scheduling control.
rf (report format)
Only one value was ever defined (afrf), and no alternative was ever implemented. There is nothing to configure.
From monitoring to enforcement: a deployment path
Do not jump straight to p=reject. Follow this three-phase approach to avoid blocking your own legitimate email.
Monitor (2-4 weeks)
Collect reports, identify all legitimate senders, fix any SPF/DKIM issues.
What to look for in reports: unknown IPs sending as your domain, SPF or DKIM failures from services you use (fix those first).
Quarantine (1-2 weeks)
Suspicious emails go to spam instead of the inbox. Continue monitoring reports for false positives.
If legitimate emails start landing in spam, check whether the sending service has proper SPF/DKIM configuration for your domain.
Reject (ongoing)
Maximum protection. Fraudulent email is blocked before it reaches recipients.
Keep monitoring reports even at reject. New services or infrastructure changes can introduce SPF/DKIM failures.
What breaks at p=reject, and how to roll back
Moving to p=reject is the moment a forgotten sender stops being a line in a report and starts bouncing real mail. Knowing the failure mode in advance turns it into a five-minute fix instead of an outage.
What breaks
Any legitimate sender that is not aligned starts getting rejected. The usual culprits:
- A SaaS tool nobody remembered, like transactional receipts from a billing platform, sending from its own domain.
- A department running its own SendGrid or Mailchimp account that was never authenticated to your domain.
- A DKIM key that was rotated or removed, so signatures that used to align now fail.
The symptom is a 5.7.1 bounce reported by the sender, and a recognised source showing disposition=reject in your aggregate reports.
How to roll back fast
Two safety nets, in order of preference:
Lower the TTL before you enforce
Publish a 300-second TTL on the _dmarc record a day before moving to reject. If you need to roll back, the change propagates in five minutes instead of hours.
Use t=y instead of a full rollback
Keep the published reject posture but ask receivers to apply the next-lower policy (quarantine) while you investigate. RFC 9989 section 4.7 defines this test flag.
With t=y, a p=reject record is applied as quarantine and a p=quarantine record is applied as none. The flag has no effect on a policy that is already none.
For a full staged rollout with the checks to run at each step, see the DMARC enforcement rollout playbook.
Worked example: a company with four email senders
Most domains do not send from one place. Here is example.com, which sends through Microsoft 365 (staff mail), Mailchimp (newsletters), Zendesk (support replies), and Stripe (payment receipts). DMARC passes when SPF or DKIM authenticates a domain that aligns with the From address, so the question for each sender is simple: does anything align?
| Sender | SPF aligns? | DKIM aligns? | What you have to do |
|---|---|---|---|
| Microsoft 365 | Yes | After you enable it | SPF aligns through include:spf.protection.outlook.com. DKIM does not sign for a custom domain until you turn it on (publish the two CNAMEs in the admin centre); until then mail is signed by your onmicrosoft.com domain, which does not align. |
| Mailchimp | No | After domain authentication | The Return-Path is a Mailchimp domain (mcsv.net and similar), so SPF authenticates Mailchimp, not you. Complete Mailchimp domain authentication so it DKIM-signs with example.com. DKIM is what carries alignment here. |
| Zendesk | No | After DKIM CNAMEs | Adding the Zendesk SPF include authorizes sending but does not align. Add the two DKIM CNAME records and enable DKIM so Zendesk signs with your domain; that is what passes DMARC. |
| Stripe | No | Only with a custom domain | By default Stripe sends receipts from stripe.com, so nothing aligns with example.com. Configure Stripe's custom email domain (its ownership, SPF, and DKIM DNS records) so receipts send from and authenticate against your domain. |
Three of the four senders rely on DKIM for alignment, and two need work before they pass. So the safe record for this company is relaxed alignment, published at quarantine while the senders are finished:
Relaxed alignment (adkim=r) matters because Zendesk often sends from a subdomain like support.example.com; relaxed lets that count as the same organization.
Do not move to p=reject until your aggregate reports confirm Stripe is the only failing source, then fix Stripe. Going to reject with Stripe still on its default domain would bounce your own payment receipts.
Vendor setup steps change. Confirm the current DKIM and custom-domain instructions in each provider's own documentation before you publish.
Common mistakes that break DMARC records
These are the errors we see most often when checking DMARC records. Each one silently invalidates your entire record.
p=reject; v=DMARC1; rua=mailto:[email protected]
Wrong tag order. v=DMARC1 must always come first. Put p= immediately after it in normal published records.
v=dmarc1; p=REJECT
Risky casing. Use uppercase DMARC1 for the version value and lowercase policy values like reject.
v=DMARC1; rua=mailto:[email protected]
Missing p= tag. RFC 9989 treats this as effective p=none, but publishing p=none explicitly is clearer for operators and tooling.
v=DMARC1; p=block
Invalid policy value. Only three values are valid: none, quarantine, reject.
v=DMARC1; p=none; [email protected]
Missing mailto: prefix. Report URIs must start with mailto:.
Want to check your record? Run a free DMARC check on your domain. If a receiver reports a permanent error evaluating your DMARC policy, that troubleshooting guide walks through the parsing faults that cause it.
Syntax rules
A few formatting rules to keep in mind when writing DMARC records:
-
Semicolons separate tags:
v=DMARC1; p=none; rua=... -
Spaces around
=and;are optional:p=noneandp = noneare both valid -
Commas separate multiple report addresses:
rua=mailto:[email protected],mailto:[email protected] - Maximum length of a single DNS TXT string is 255 characters. Longer records are automatically split into multiple strings and concatenated by DNS
- No trailing semicolon is required, but it does not cause errors if present
A DMARC record rarely hits the 255-character limit, but a long rua list with several addresses can. When it does, split it into adjacent quoted strings; DNS concatenates them with no separator added:
That is a BIND zone-file split. Managed DNS providers like Cloudflare and Route 53 do the split for you: paste the full record and they store it correctly.
Testing your DMARC record
After publishing your record, verify it from the command line:
DNS changes can take up to 48 hours to propagate, but most updates are visible within minutes.
Or use our DMARC checker for a full analysis with specific fixes.
Deep dive: formal ABNF grammar (for developers)
If you are building a DMARC parser, validator, or generator, use the complete ABNF in RFC 9989. The excerpt below is a simplified map of the record shape; it uses ABNF (Augmented Backus-Naur Form) notation as defined in RFC 5234, but it is not a substitute for the full grammar.
Key rules from the grammar
-
Version ordering is mandatory:
v=DMARC1comes first. Other tags are unordered, though puttingp=second is the clearest convention. -
*WSPmeans optional whitespace around=and;separators. -
%s"DMARC1"means case-sensitive string match. "DMARC1" only, not "dmarc1". -
URI scheme: Only
mailto:is defined for rua/ruf in normal deployments. The old!size suffix is obsolete. - Multiple TXT strings: DNS concatenates the quoted strings automatically. The 255-octet limit on a single character-string is defined by RFC 1035 Section 3.3. Split at 255 characters, preferably after a semicolon.
IANA DMARC tag registry
The official IANA registry lists all standardized tags. RFC 9989 (May 2026) added np (non-existent subdomain policy), psd (public suffix domain flag), and t (test mode flag), and removed pct, rf, and ri. Records keep using v=DMARC1 for backward compatibility.
Frequently asked questions
What does a DMARC record look like?
A DMARC record is one line of DNS text that begins with v=DMARC1 and a policy, for example v=DMARC1; p=reject; rua=mailto:[email protected]. It is published as a TXT record at _dmarc.yourdomain.com. The tags set the policy (p, sp, np), where reports are sent (rua), and how strictly senders must align (adkim, aspf).
What is RFC 7489?
RFC 7489 is the original DMARC specification (Domain-based Message Authentication, Reporting, and Conformance), published in March 2015 via the Independent Submission Stream of the RFC Editor with Informational status. It is not an IETF Standards Track document and does not carry formal IETF endorsement. It was obsoleted in May 2026 by RFC 9989, while deployed records continue to use v=DMARC1.
When was RFC 7489 published?
RFC 7489 was published in March 2015 via the Independent Submission Stream of the RFC Editor, not by the IETF itself. It was authored by M. Kucherawy and E. Zwicky (Yahoo!) and carries Informational status.
What does RFC 7489 define?
RFC 9989 (DMARCbis) defines 11 active DMARC tags for DNS TXT records: version (v), policy (p), subdomain policy (sp), non-existent subdomain policy (np), test mode (t), public suffix domain flag (psd), aggregate reporting (rua), failure reporting (ruf), alignment modes (adkim, aspf), and failure reporting options (fo). Three RFC 7489 tags (pct, rf, ri) were removed. These tags are published at _dmarc.yourdomain.com.
Is RFC 7489 still the current DMARC standard?
It was the de facto reference email receivers and vendors implemented from 2015 through 2026, but it is not an IETF standard. The IETF Datatracker lists RFC 7489 as an Independent Submission not endorsed by the IETF. The IETF's DMARC Working Group published the Standards Track replacement in May 2026 as RFC 9989 (core protocol), RFC 9990 (aggregate reporting), and RFC 9991 (failure reporting). RFC 9989 obsoletes RFC 7489 and RFC 9091 but is backward-compatible with v=DMARC1, so records built against RFC 7489 continue to work.
What is the difference between RFC 7489 and RFC 9989?
RFC 7489 (March 2015) is the original DMARC specification, Informational, from the Independent Submission Stream. RFC 9989 is the IETF Standards Track revision from the DMARC Working Group; it obsoletes both RFC 7489 and RFC 9091 (the experimental PSD DMARC extension), makes pct, rf, and ri historic, adds np, psd, and t=, and clarifies policy and alignment rules. Both use the v=DMARC1 version identifier, so existing records remain valid.
Are DMARC tag names case-sensitive?
In practice receivers parse tag names case-insensitively, so p= and P= behave the same. RFC 9989 does not state this explicitly. The one value it does fix as case-sensitive is the version string, which must be exactly DMARC1.
What is the np tag in DMARC?
The np tag sets a policy specifically for non-existent subdomains (names that do not resolve in DNS). RFC 9989 added it to core DMARC in May 2026. Valid values are none, quarantine, and reject, identical to p and sp. Setting np=reject on a domain that never uses subdomains asks receivers to reject spoofed names like support.example.com that you never created.
What is the sp tag in DMARC and when should I use it?
The sp tag sets a policy for subdomains that differs from the Organizational Domain policy in p. If sp is absent, subdomains inherit the p policy. A common pattern is p=none; sp=reject on a parent domain when you want strong subdomain protection while still monitoring the main domain. Valid values are none, quarantine, and reject.
What does aspf do in a DMARC record?
The aspf tag controls SPF alignment mode between the SPF-authenticated Return-Path domain and the From header domain. aspf=r (relaxed, the default) allows subdomains to align, so mail from mail.example.com aligns with example.com. aspf=s (strict) requires exact domain matches. Keep aspf=r unless every one of your senders uses the exact Organizational Domain as their Return-Path.
Additional resources
Standards and specifications
- RFC 7489 - Domain-based Message Authentication, Reporting, and Conformance (DMARC)
- RFC 7208 - Sender Policy Framework (SPF)
- RFC 6376 - DomainKeys Identified Mail (DKIM)
- RFC 9989 - DMARC (May 2026, obsoletes RFC 7489 and RFC 9091)
- RFC 9990 - DMARC Aggregate Reporting
- RFC 9991 - DMARC Failure Reporting
- RFC 9091 - Experimental PSD DMARC extension (obsoleted by RFC 9989)
- IANA DMARC Parameter Registry
Tools
- Free DMARC generator - Build an RFC 9989-aware record step by step
- DMARC checker - Validate your domain's current configuration
- Top 100 domains by DMARC compliance