DMARC, and how to read the reports
DMARC tells receivers what to do when SPF or DKIM alignment fails, and where to send reports. Gmail and Yahoo require it for bulk senders. This guide covers policy choice, DNS setup, and how to read the XML reports you will receive.
DMARC, and how to read the reports
DMARC lets the domain named in your From header tell receivers what to do when SPF or DKIM do not align. It also tells them where to send reports. If you send at scale, you need it. Gmail and Yahoo both require DMARC for bulk senders, and having no policy can lead to delays or rejection.
This guide explains the policy you publish in DNS, what the tags mean, how to avoid the common traps, and how to read the XML reports you will receive.
Before you start
This picks up from a mail setup you can already send from and that you can reach over the web, with SPF and DKIM available for each source that uses your domain. If you do not have that, get SPF and DKIM in place for your senders first.
- Access to DNS for your domain: you will publish one TXT record at
_dmarc.<your-domain>. If your domain points at Hostworld for hosting, set your nameservers at your registrar to ns1.serverworld.uk, ns2.serverworld.uk, ns3.serverworld.uk and ns4.serverworld.uk. You can then add the DMARC record in cPanel’s Zone Editor. - Choose where reports will go: DMARC sends aggregate reports (RUA) to one or more
mailto:addresses. Failure reports (RUF) are optional and can include message content, so plan for privacy if you enable them. - Only one DMARC record is valid: if multiple TXT records exist at
_dmarc.<domain>, receivers discard them all. Consolidate into a single record before testing. - v= tag rules: the record must begin with
v=DMARC1(exact case). If it is not first, the whole record is ignored. - Defaults that bite:
adkimandaspfdefault to relaxed, not strict. Unknown tags are ignored. A malformedv=voids the record. - Which spec applies: DMARC as deployed today is RFC 7489. A revision (known as DMARCbis) has been worked on for some years, but until receivers say otherwise, write your record against RFC 7489 and the published requirements of the mailbox providers you send to.
- External reporting authorisations: if your
rua=orruf=points to another domain, that domain must publish an authorisation record in DNS or receivers will ignore that destination. - Caching: updates to report authorisations and DMARC itself follow DNS TTL. Do not assume an immediate switch in where reports land.
Step 1: Decide your starting policy
What this does: you define the action for mail that fails alignment and where to send reports. You start with monitoring, then move to enforcement after you have reviewed the data.
- Policy options:
p=none(monitor),p=quarantine(treat as suspicious),p=reject(do not accept). - Staged rollout: the usual approach is to move from
p=nonetop=quarantine, then top=reject, once you have assessed reports and handled indirect flows such as forwarders and mailing lists. - Ramping tag:
pct=sets the percentage of failing messages the published policy is applied to. The rest are handled as if the next lower policy applied. The default is 100.
Step 2: Plan subdomain policy
What this does: you control how your policy applies to subdomains.
sp=sets subdomain policy. If absent, subdomains inheritp=.- Use
sp=to keep stricter control on the apex while giving project subdomains room to fix alignment. For example:p=reject; sp=quarantine. - Remember that a subdomain with no DMARC record of its own is covered by what you publish at the apex, so decide the policy deliberately rather than leaving it to chance.
Step 3: Publish the DMARC TXT record
What this does: you place a TXT record at _dmarc.<your-domain> that receivers will fetch. The only valid value is a single TXT record that begins with v=DMARC1.
If your DNS is with Hostworld
If your domain uses our nameservers (ns1.serverworld.uk to ns4.serverworld.uk), the zone is managed in cPanel. In short: open Zone Editor for the domain, add a TXT record, set the name to _dmarc and paste the value for the policy you want from the examples below. For the click-by-click version with each screen named, see how to add a TXT record in cPanel’s Zone Editor. If the record is published and mail is still failing alignment, open a support ticket and we will look at the live record with you.
If your DNS is elsewhere
Create a TXT record at the host name _dmarc under your domain, with one of the values below. If you would rather keep the zone with us, point the domain at our nameservers first and then use the cPanel route above.
Examples you can adapt
Monitoring only, aggregate reports to one address:
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=none; rua=mailto:[email protected]"
Monitoring to two addresses:
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=none; rua=mailto:[email protected],mailto:[email protected]"
Move to quarantine, applied to a quarter of failing mail during rollout. Relaxed alignment:
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=quarantine; pct=25; adkim=r; aspf=r; rua=mailto:[email protected]"
Enforcement at the apex, softer on subdomains, strict alignment:
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=reject; sp=quarantine; adkim=s; aspf=s; rua=mailto:[email protected]"
- Keep a single TXT record. Do not split DMARC across multiple TXT records at the same name.
- Begin with
v=DMARC1. If it is not first, the record is ignored. - Remember the
mailto:prefix inrua=andruf=. - Within one
rua=orruf=value, separate multiple URIs with commas. If a comma or exclamation mark must appear inside a single URI, percent-encode it. For example:mailto:dmarc+uk%[email protected].
Step 4: Authorise external report collectors, if you use them
What this does: it allows receivers to send your DMARC reports to an address in someone else’s domain.
- Decide the destination, for example
rua=mailto:[email protected]. - Ask the operator of
reports.example.netto publish a TXT record that authorises your domain to send reports there. The required name is<your-domain>._report._dmarc.<reporting-domain>and it must include at leastv=DMARC1. Wildcards are allowed on their side if they choose to use them.
Example authorisation that the reporting domain would host for you:
yourdomain.example._report._dmarc.reports.example.net. 3600 IN TXT "v=DMARC1"
- If that authorisation is missing, receivers will ignore the external address in your
rua=orruf=. Teams often mistake this for “no one is sending reports”. - Changes to these authorisations follow DNS TTL.
Step 5: Verify the record from the command line
What this does: it confirms your record is visible and syntactically usable. It also catches the “more than one record” mistake.
Linux or macOS
Command: query the TXT records at _dmarc.<domain> with dig.
dig +short TXT _dmarc.example.com
What to look for: one TXT string that starts with "v=DMARC1;…". If you see more than one, consolidate them. If you see no output, check the name and the zone’s nameservers.
Windows
Command: use nslookup in interactive mode.
nslookup
set type=TXT
_dmarc.example.com
What to look for: the same single TXT response, beginning with v=DMARC1. If the record appears quoted across multiple lines, that is fine. What matters is that receivers assemble one DMARC policy from it.
Step 6: Read aggregate (RUA) reports
What this does: aggregate reports show, per receiver and per source IP, how your mail authenticated and how the receiver applied your policy. The XML schema is given in RFC 7489, Appendix C.
You will receive a compressed XML attachment at the rua= address. Unzip it and open the XML in a viewer or parser. Key elements to look for:
- report_metadata: who sent the report, a unique report_id, and the date_range.
- policy_published: the policy that receiver discovered and applied:
p,sp,pct, and alignment modes. - record: one per source. Each contains:
- row:
source_ipandcount, pluspolicy_evaluatedwithdispositionand thedkim/spfpass or fail. - identifiers: the header From domain and any d= (for DKIM) or helo/return-path domains the receiver evaluated for alignment.
- auth_results: per-method pass or fail details.
- row:
Minimal example, annotated:
<feedback>
<report_metadata>
<org_name>Receiver Ltd</org_name>
<report_id>20260915-12345</report_id>
<date_range><begin>1694736000</begin><end>1694822400</end></date_range>
</report_metadata>
<policy_published>
<domain>example.com</domain>
<p>quarantine</p><sp>none</sp><pct>100</pct>
<adkim>r</adkim><aspf>r</aspf>
</policy_published>
<record>
<row>
<source_ip>203.0.113.25</source_ip><count>54</count>
<policy_evaluated><disposition>none</disposition><dkim>pass</dkim><spf>fail</spf></policy_evaluated>
</row>
<identifiers><header_from>example.com</header_from></identifiers>
<auth_results><dkim><domain>example.com</domain><result>pass</result></dkim><spf><domain>mailer.example.net</domain><result>pass</result></spf></auth_results>
</record>
</feedback>
How to use this data:
- Group by source_ip. Unknown IPs sending at volume merit investigation. Check if a supplier or a forwarder is involved.
- Check policy_evaluated. If
dkimis pass and alignment is relaxed, SPF can fail without consequence. That is often fine. If both DKIM and SPF are failing alignment for your domain, find out why before moving to enforcement. - Look at identifiers. They show which domains were evaluated for alignment. If your ESP uses
d=on your domain, DKIM will align even if the return-path is their domain. - Note policy_published. If you expected strict alignment but see
adkim=randaspf=r, that is the default. Tighten only after you confirm all legitimate sources align. - Keep an eye on disposition. Under
p=quarantineorp=reject, a high count of quarantine or reject dispositions on legitimate sources means you moved too far, too fast.
Step 7: Move to enforcement in stages
What this does: it reduces spoofing that uses your domain by telling receivers to quarantine or reject messages that fail alignment.
- Run at
p=nonewithrua=for long enough to see your normal traffic pattern. That might be a full business cycle. The exact timing is your call. - Fix obvious alignment issues. For each sender:
- Ensure SPF includes the sending IP or host and that the visible From domain aligns with the SPF domain in relaxed mode.
- Ensure at least one DKIM signature uses your domain in
d=and passes. DKIM alignment often survives forwarding better than SPF. - Decide if you can move to strict alignment later. Some SaaS platforms cannot sign with your domain.
- Switch to
p=quarantine. Consider a lowpct=value for a bedding-in phase, then raise it as the reports come back clean. - Review aggregate reports again. Address any legitimate traffic that is getting quarantined. Watch forwarders and mailing lists in particular.
- When comfortable, move to
p=reject. If subdomains are varied, you can keepsp=quarantinewhile the apex is at reject.
Example enforcement record with staged subdomain policy:
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=reject; sp=quarantine; adkim=r; aspf=r; rua=mailto:[email protected]"
Step 8: Use failure (RUF) reports cautiously
What this does: per-message diagnostics that can include headers and sometimes content. Not all receivers send them even if you request them.
- Enable only if you have a clear reason to debug a problem. Treat the mailbox as sensitive.
- Example addition that asks for failure reports and sets failure options:
_dmarc.example.com. 3600 IN TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1"
- If
ruf=points outside your domain, the same external reporting authorisation rules apply as forrua=.
Troubleshooting and gotchas
- No reports arriving: check you used
mailto:, and check any external destination is authorised by the reporting domain. Not every receiver sends to every destination you list. - Ramping too fast: a
pct=value only reduces how much failing mail gets the published treatment. It does not fix a sender that cannot align, so use the reports to find those first. - Multiple DMARC records: fix immediately. Receivers will ignore all of them until you have a single record.
- Strict alignment too soon: switching
adkim=s/aspf=swithout checking every sender can align will cause legitimate mail to fail under enforcement. - Validator disagreements: if an online checker claims a different policy applies to a subdomain than the receiver’s report shows, trust the report. It tells you what was actually applied to your mail.
What next
If you run your own mail server on a VPS and want to test alignment end to end, see our VPS guides. If you need a machine to host your own mail stack, our London VPS line is available in the UK and in New York.
If the record is in a zone we host and you want a second pair of eyes on it, open a support ticket from your account so we can look at the live record with you. For the exact screens in cPanel, use how to add a TXT record in cPanel’s Zone Editor.
The next step in this playbook is: bring all legitimate senders into SPF/DKIM alignment so you can move from monitoring to enforcement with confidence.
Common questions
Do I really need DMARC?
For small, low-volume sending you can operate without DMARC, though you will miss the visibility reports provide. For bulk sending, Gmail and Yahoo’s 2024 policies require DMARC with a published policy. Lack of DMARC or lack of a policy can cause rate limits or rejection. For any domain that people might spoof, DMARC reduces risk when you move to enforcement after reviewing reports.
Where exactly does the DMARC record live and what must it start with?
Publish a single TXT record at _dmarc.<your-domain>. The first tag must be v=DMARC1. If v=DMARC1 is not first, receivers ignore the record. If more than one DMARC TXT record exists at that name, receivers discard them all.
Can I send reports to more than one address?
Yes. List multiple mailto: URIs in one rua= separated by commas. RFC 9989 says receivers should send a report to each listed URI, though they may still limit fan-out. Remember to percent-encode commas or exclamation marks if they are part of a single URI. Example: rua=mailto:[email protected],mailto:[email protected].
Why am I not receiving the reports I expected?
Common issues include leaving out mailto:, pointing rua= to another domain without the required external authorisation record, and duplicate DMARC records. Also note that authorisation changes take effect according to DNS TTL, so delivery to a new external destination may not start or stop immediately.
Should I set strict alignment?
Only after you confirm in aggregate reports that every legitimate source aligns under strict mode. The defaults are relaxed: adkim=r, aspf=r. Strict alignment can improve protection, but applying it too early can make genuine traffic fail and be quarantined or rejected once you enforce.
What happened to pct and other sampling settings?
pct is now historic in RFC 9989 and should not be used. The spec introduces t=y to request one-step-down handling during testing. That is the supported way to soften enforcement while you finish alignment work.
Do I need failure reports (RUF)?
Usually not. RUF reports contain per-message diagnostics and can include headers and sometimes content, so treat them as sensitive. Not all providers send them. Use them for short-term debugging with a secured mailbox, then disable.
Was this guide helpful?
0 people found this helpful