RE:NODE

App hosting11 min read

DMARC reports and policy rollout: from p=none to reject

How to read DMARC aggregate reports, sort the senders they reveal, fix alignment, and move a domain from p=none to quarantine and reject without losing real mail.

0 readers

A DMARC rollout is three policies and the evidence between them. You publish p=none with a rua address, collect daily aggregate reports from the big receivers for two to four weeks, fix every legitimate sender that fails alignment, then move to p=quarantine and finally p=reject, reading the reports at each step. The reports are the point. They are the only view you get of who is sending mail with your domain in the From: line across the internet - your own servers, the services you forgot about, the forwarders, and the people impersonating you. Going straight to p=reject without reading them is how organisations discover their invoicing system was never authenticated, on the day customers stop receiving invoices.

This post assumes you know what SPF, DKIM and DMARC are - if not, start with SPF, DKIM and DMARC explained. Here the focus is on the reports and the rollout.

The record, tag by tag, for a rollout#

TXT at _dmarc.example.com - the starting point
v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com; fo=1

The tags that matter while rolling out:

TagValuesRole in a rollout
pnone, quarantine, rejectThe policy for the domain itself
spsamePolicy for subdomains; defaults to p
ruamailto: addressesWhere aggregate reports go - essential
rufmailto: addressesPer-message failure reports - rarely sent
pct0-100Share of failing mail the policy applies to
adkim / aspfr, sRelaxed or strict alignment
fo0, 1, d, sWhen failure reports are generated
risecondsRequested report interval; default 86400

fo=1 asks for failure reports when any mechanism fails rather than only when all do. It only affects ruf reports, which most large receivers do not send for privacy reasons, so it does little harm and occasionally helps.

ri is a request. Receivers send daily regardless, so leave it out.

What an aggregate report contains#

Aggregate reports arrive as email attachments - gzipped or zipped XML, one per receiver per day, sent by the likes of Google, Microsoft, Yahoo and many smaller providers. Each describes the mail that receiver saw claiming your domain, grouped by sending IP and result. Trimmed to the essentials:

a DMARC aggregate report, trimmed
<feedback>  <report_metadata>    <org_name>google.com</org_name>    <date_range><begin>1791331200</begin><end>1791417599</end></date_range>  </report_metadata>  <policy_published>    <domain>example.com</domain><p>none</p><adkim>r</adkim><aspf>r</aspf>  </policy_published>  <record>    <row>      <source_ip>203.0.113.25</source_ip>      <count>412</count>      <policy_evaluated>        <disposition>none</disposition><dkim>pass</dkim><spf>pass</spf>      </policy_evaluated>    </row>    <identifiers><header_from>example.com</header_from></identifiers>    <auth_results>      <dkim><domain>example.com</domain><selector>s2026a</selector><result>pass</result></dkim>      <spf><domain>example.com</domain><result>pass</result></spf>    </auth_results>  </record></feedback>

Read each record as a sentence: "From IP 203.0.113.25, 412 messages with From: example.com; DKIM passed aligned, SPF passed aligned; we did nothing to them because the policy is none." The policy_evaluated block gives the aligned DMARC verdicts. The auth_results block gives the raw SPF and DKIM results with the domain each one was for - which is how you see that SPF passed, but for bounces.provider.example, which is not aligned.

Nobody reads these by eye past the first week. Feed them to a parser: parsedmarc is a widely used open-source one that turns reports into a searchable dashboard, and many commercial services do the same with less setup. Some mail servers also process incoming reports themselves - recent versions of Stalwart can analyse DMARC reports delivered to the addresses you configure and show them in the web admin - which is enough for a small domain.

Use a dedicated address for reports. A busy domain receives dozens a day, and they are not something a person wants in their inbox.

Sorting the senders you find#

After two weeks of reports you will have a list of source IPs. Every one falls into one of four groups, and each has a different action.

  1. Your own infrastructure, aligned. Your mail server, passing DKIM with your domain. Nothing to do.
  2. Legitimate services, not aligned. The newsletter platform, CRM, helpdesk, billing system, recruiting tool - sending as your domain but passing SPF and DKIM only for their own domains, or not at all. These are the real work. Look up the provider from the IP's reverse DNS or an IP lookup, then enable DKIM with your domain in their settings and, where offered, a custom return-path domain.
  3. Forwarders. University aliases, old addresses forwarding to Gmail, mailing lists. SPF fails because the forwarder's IP is not yours; DKIM often still passes if the message was not modified. You cannot fix these, and with DKIM passing you do not need to.
  4. Spoofers. IPs with no relationship to you, failing everything, often in countries you do not send from. These are what DMARC enforcement is for. Note them and move on.

Volume helps you prioritise. A legitimate service sending 3,000 messages a month unaligned matters; a forwarder relaying six messages does not.

A sender that only shows up once a month - payroll, quarterly statements, the annual renewal notice - is easy to miss in a two-week window. Ask around before moving on: finance, HR, marketing and whoever runs the website forms each know about senders IT has never heard of.

Identifying an unknown IP

An IP address in a report is only useful once you know whose it is. Three quick checks usually settle it:

bash
# Reverse DNS often names the provider outright$ dig +short -x 198.51.100.77# Who holds the address block$ whois 198.51.100.77 | grep -iE 'orgname|org-name|netname|descr'

Then look at the DKIM domain and selector in the same report row: a signature by d=sendgrid.net or a selector like pm tells you the service even when the IP says nothing. If an IP belongs to a large cloud provider and no signature names a service, ask your colleagues what runs there before you assume it is hostile.

A worked example: the senders nobody listed#

A small company with its own mail server publishes p=none and points rua at a reports mailbox. After three weeks, the parsed reports show five sources sending as example.com:

  1. Their own mail server, 6,200 messages, DKIM and SPF both aligned. Fine.
  2. A helpdesk platform, 900 messages, SPF passing for the platform's bounce domain, DKIM signed by the platform's own domain. Neither aligned - every ticket reply would be rejected under p=reject.
  3. An accounting package, 140 messages, all on the last two days of the month, no DKIM at all, SPF failing. Nobody in IT knew it sent mail; finance had configured it to send invoices as accounts@example.com.
  4. A university forwarding address belonging to one employee, 30 messages, SPF failing, DKIM passing. Nothing to do.
  5. Twelve IPs across three countries, 2,000 messages, failing everything. Spoofing.

The fixes take an afternoon. The helpdesk offers DKIM with a custom domain: two CNAME records, a verification click, and its signatures now carry d=example.com. The accounting package cannot sign, but it can send through an SMTP server, so finance points it at the company's own mail server's submission port with a dedicated account, and the invoices are now signed by Stalwart like everything else.

A week later the reports show sources 1 to 3 aligned. The company moves to p=quarantine, then a month later to p=reject. The spoofing in group 5 continues to appear in reports - now with a disposition of reject against every message. That last line is the whole return on the exercise.

Alignment, precisely#

DMARC passes if SPF or DKIM passes and the domain it passed for aligns with the domain in From:.

  • DKIM aligns when the signature's d= domain matches the From: domain.
  • SPF aligns when the envelope sender's domain (the MAIL FROM, shown as Return-Path) matches the From: domain.

In relaxed mode (r, the default) "matches" means the same organisational domain: mail.example.com aligns with example.com, and both align with news.example.com. The organisational domain is worked out with the Public Suffix List, which is why example.co.uk works correctly while co.uk is never treated as one organisation. In strict mode (s) the domains must be identical.

Leave both at relaxed. Strict alignment breaks the custom return-path subdomains that make SPF align for third-party senders, and buys nothing that matters for most domains.

The rollout, step by step#

2-4 weeks of reportsno legitimate failures2+ quiet weeksnew sender appearsp=nonecollect reportsFix sendersDKIM with your domainp=quarantineramp pctp=rejectkeep reading reports
A DMARC rollout and what decides each step
  1. Publish `p=none` with `rua`. Wait two to four weeks. Include at least one month-end if your organisation sends invoices.
  2. Fix every legitimate unaligned sender the reports show. Re-check the reports a week after each fix to confirm the change took.
  3. Move to `p=quarantine`. If you are nervous, use pct to apply it gradually: pct=25 sends a quarter of failing mail to spam and treats the rest as none. Raise to pct=100 after a week or two with no complaints.
  4. Hold at `quarantine` for at least two weeks with nothing legitimate failing.
  5. Move to `p=reject`. Failing mail is now refused during the SMTP conversation, so a misconfigured sender gets a bounce rather than silently landing in spam - which is better for diagnosis than quarantine.
  6. Keep the `rua` address. New services get added, someone changes a provider, a key rotation goes wrong. The reports are how you find out within a day instead of a month.

The pct tag has always been honoured inconsistently - some receivers effectively treat anything below 100 as "not enforced". A revision of the DMARC specification (often called DMARCbis) is moving away from it in favour of a simpler testing flag. Use pct as a gentle ramp if you like, but do not rely on it for fine control.

Subdomains deserve a thought before step 5. sp= sets the policy for subdomains, defaulting to the domain's own p. If you send from subdomains such as news.example.com, check them in the reports too. If you never send from subdomains, sp=reject from early on shuts off a favourite spoofing trick at little risk.

What breaks at p=reject#

Three kinds of mail can still fail after a careful rollout, and you should know about them before enforcing.

  • Mailing lists that modify messages. A list that adds a subject prefix or footer breaks DKIM, and the list server's IP fails SPF for your domain. Most modern list software works around DMARC by rewriting the From: to the list's own address for posters from p=reject domains, and ARC (Authenticated Received Chain) lets lists pass along the original verdict for receivers that trust them. Older lists may still bounce your members' posts.
  • Forwarding that modifies messages. Plain forwarding usually survives on DKIM. Forwarding through a security gateway that rewrites links does not.
  • Devices and scripts that send directly. The office scanner that emails PDFs, the NAS that sends alerts, the cron job on a forgotten server that mails a report - each sending as your domain straight to the recipient, unsigned. They tend to send to internal addresses, so they may never appear in reports from Google or Microsoft, and they break quietly. Point every one of them at your own mail server's submission port with an account of its own, so their mail is signed like everyone else's.

None of them is a reason to stay at p=none forever. They are a reason to keep reading the reports after you enforce, and to know what to tell a colleague whose post to an old mailing list bounced.

Why bother: the receivers' requirements#

Since February 2024, Google and Yahoo require anyone sending more than about 5,000 messages a day to their users to publish a DMARC record (at least p=none), with SPF and DKIM passing and aligned. Microsoft announced similar requirements for high-volume senders to Outlook.com addresses in 2025. Smaller senders are held to a lighter standard, but a domain with no DMARC at all is increasingly treated as suspect. And a domain at p=reject is far less attractive to spoof, because the spoofed mail is refused at every major receiver. Why email goes to spam puts DMARC in the context of everything else receivers check.

DMARC with a RE:NODE Mail Server#

On a Mail Server plan, Stalwart signs your outgoing mail with the DKIM keys its web admin generates for each domain, which gives you aligned DKIM from your own server on day one. The DMARC record itself is yours to publish, alongside MX, SPF and DKIM, wherever your DNS is hosted - there is no zone editor on our side. A mailbox on the same server makes a natural rua destination for the reports. The rest of the work - finding and fixing the other services that send as your domain - is the same wherever your mail lives. DKIM keys and rotation covers the signing side.

FAQ#

How long should I stay at p=none?

At least two weeks, better four, and long enough to include any monthly sending such as invoices or statements. Move on when every legitimate sender in the reports is aligned, not when the calendar says so.

Why am I not receiving any DMARC reports?

Check the rua syntax (mailto: is required), check that the record is at _dmarc.example.com, and if the address is on another domain, check that domain publishes the authorisation record. Reports also take a day or two to start, and a domain that sends little may get few.

Why do I never get ruf failure reports?

Most large receivers do not send them, because they can contain message content and personal data. Aggregate reports are what you will actually get, and they are enough.

Is quarantine safer than reject?

It is gentler on a mistake, since failing mail goes to spam rather than bouncing. But a misconfigured sender is harder to notice under quarantine, because nobody gets a bounce. Treat quarantine as a stage, not a destination.

Do I need DMARC on domains that never send mail?

Yes, and go straight to p=reject with v=spf1 -all and a null MX. There is nothing legitimate to break, and parked domains are favourites for spoofing.


Comments

Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.

0/2000