Rolling out DMARC: from none to reject
Module 4: Deliverability: SPF, DKIM and DMARC in practice · Reading time: 12 minutes
Learning objective: After this lesson, you can explain how alignment works, plan a phased DMARC rollout from p=none to p=reject, choose the right tags (rua, sp, np, t) and deal with the well-known pitfalls around forwarding and mailing lists.
Key concepts: DMARC (RFC 9989), Author Domain (the domain in the From address), alignment, relaxed and strict (adkim, aspf), organisational domain, DNS tree walk, p=none, p=quarantine, p=reject, rua, sp, np, t=y (testing mode), deprecated tags pct, rf, ri, mailing lists, From rewriting, ARC
What DMARC actually checks
DMARC answers a single question for every incoming email: does SPF or DKIM pass for a domain that belongs to the From address? The domain in the From address is called the Author Domain in the standard. The basics of the record are covered in the DNS course, lesson 4.5. In May 2026 the revised standard was published: RFC 9989, with RFC 9990 for aggregate reports and RFC 9991 for failure reports. Existing records with v=DMARC1 remain valid.
Alignment in practice
"Belongs to" is called alignment. There are two modes:
- relaxed (default): the domains share the same organisational domain.
nieuws.example.comandexample.comare aligned;example.comandexample.netare not. - strict (
adkim=soraspf=s): the domains must match exactly.
For SPF, DMARC compares the domain of the Return-Path with the From domain. For DKIM it compares the d= domain of a valid signature. A few examples for an email with From: info@example.com:
| SPF result (Return-Path) | DKIM result (d=) | DMARC |
|---|---|---|
pass for example.com | no signature | pass (SPF aligned) |
pass for bounce.mailer.example | pass for mailer.example | fail (both pass, neither aligned) |
pass for bounce.mailer.example | pass for example.com | pass (DKIM aligned) |
| fail (forwarded) | pass for example.com | pass (DKIM survives) |
pass for bounce.example.com | none | pass with relaxed, fail with aspf=s |
So leave adkim and aspf on relaxed unless you have a good reason not to.
How does a recipient know what the organisational domain is? It used to be done with the Public Suffix List, a list of domains such as .nl, .co.uk and github.io. RFC 9989 replaces that with a DNS tree walk: the recipient looks up _dmarc records for the domain and its parent domains. For an ordinary user, nothing changes; you'll only notice this if you work with records on subdomains.
The rollout in four phases
The goal is p=reject: then recipients refuse email that pretends to be from you, which is the best protection against fake invoices and phishing in your name. But going straight to reject without knowing your senders means you'll end up rejecting your own invoices. So follow this order (the recommended approach for this course):
Phase 0: preparation
- Make an inventory of all your senders (lesson 4.2).
- Make sure every sender has SPF or DKIM aligned; preferably DKIM, since that survives forwarding.
- Set up a separate address for reports, for example
dmarc@example.com, or use a reporting service. You'll quickly receive several reports a day.
Phase 1: measuring with p=none
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"p=none doesn't do anything to the email itself. Recipients deliver everything as usual, but send you a daily aggregate report listing every server that sent mail on behalf of your domain and whether SPF, DKIM and DMARC passed. This also satisfies the minimum requirement from Gmail, Yahoo and Microsoft for bulk senders (lesson 5.3).
Leave this in place for at least two to four weeks, and longer if you have services that only send mail occasionally (an annual reminder, a quarterly invoice). Read the reports (lesson 4.5) and fix any of your own sources that fail.
Phase 2: p=quarantine
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"Email that fails DMARC goes to the recipient's spam folder. If you forget a source, the email isn't lost, but it is hard to find. If you want to be cautious, add t=y first (testing mode): recipients then apply a milder policy (so none instead of quarantine), but you can see in the reports what would happen. This is the RFC 9989 replacement for the old pct= tag.
Watch the reports for a few more weeks.
Phase 3: p=reject
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"Email that fails DMARC is rejected. The sender gets a bounce, for example with code 5.7.509 at Microsoft, or a reference to the DMARC policy at Gmail (module 6). Keep monitoring the reports: new services always turn up.
When can you move faster?
If all your email goes through a single provider that handles SPF and DKIM for you, and nothing else sends mail on behalf of your domain, you can set a strict policy straight away. Some hosting companies therefore set p=reject as the default. If you later start using a newsletter service or accounting software, temporarily set it back to p=none with a report address until that service is properly set up.
The other tags
| Tag | What it's for | Advice |
|---|---|---|
rua=mailto:... | Address(es) for aggregate reports, separated by commas | Always fill in during the rollout |
ruf=mailto:... | Address for failure reports per email (RFC 9991) | Almost no recipient sends them, and they may contain personal data. Usually leave it out |
sp= | Policy for existing subdomains | Leave out (then p= applies), unless subdomains send mail differently |
np= | Policy for subdomains that don't exist | np=reject is a good addition once your main policy is strict: then nobody can send mail from factuur.example.com if that name doesn't exist |
adkim=, aspf= | Strict or relaxed | Leave on relaxed |
t=y | Testing mode: one step milder | Useful during the transition to quarantine or reject |
fo= | When failure reports are generated | Only useful together with ruf |
pct=, rf=, ri= | Deprecated in RFC 9989 | No longer use them; recipients following the new standard ignore them |
A report address on a different domain (for example, a reporting service) only works if that domain grants permission with a record such as example.com._report._dmarc.rapportdienst.example. The service usually arranges this itself (RFC 9990, chapter 4).
Pitfalls
Mailing lists
A classic mailing list forwards your email to all members from its own server, often adding [list] to the subject or a footer. That breaks SPF (different server) and DKIM (email changed). With p=reject, recipients then reject your message to the list. Modern list software solves this by rewriting the From address to the list's address ("Jan via Members"), or by forwarding the email unchanged. If you use a list that doesn't do this, you'll see it in your reports.
Forwarding
See lesson 3.3: SPF breaks, DKIM usually survives. A recipient can use ARC to decide to trust a known forwarder. In the reports, you'll recognise this as email from an unknown server with DKIM pass and SPF fail; that's not a reason to relax your policy.
Two records or a typo
Two DMARC records on _dmarc make the policy invalid, and so does a typo in p= (p=rejected doesn't exist). Check after every change.
In practice: what it looks like in a panel
With a WebOké hosting package, v=DMARC1;p=reject is set by default, without a report address. That's safe as long as all your email goes through those servers. If you also send mail via other services, set it to p=none with a rua address and work through the phases. In DirectAdmin, you do this in DNS Administration using the pencil icon next to the _dmarc record (fields Domain policy type and Aggregate Email (RUA)); in My WebOké, using the DMARC helper on the DNS tab. With other providers, you create a TXT record on the name _dmarc and type the text yourself; the result is the same.
Summary
- DMARC passes if SPF or DKIM passes for a domain aligned with the From domain; relaxed alignment accepts subdomains.
- Rollout: inventory,
p=nonewithruaand reading reports,p=quarantine(optionally witht=y), thenp=reject. - Use
np=rejectfor non-existent subdomains once your main policy is strict.pct,rfandriare deprecated. - Mailing lists and forwarding cause expected failures; DKIM and ARC catch some of these.
- Exactly one record on
_dmarc, with no typos.
Quiz
Exercise
Exercise Z4.4: Checking your domain's DMARC and choosing the next step. Enter your own domain (or internet.nl). Fill in the DMARC record as you found it, the value of p= and whether it contains a rua address. Then choose which phase of the rollout you think is the next step, and why. The tool looks up the record live, checks the syntax against RFC 9989 (one record, valid p, known tags, deprecated tags as a warning), and puts your answers alongside it.
Further reading
The steps in these articles apply to WebOké's panels; with other providers it works similarly.
- Free DNS course 4.5: DMARC: what receivers should do with fake mail
- DirectAdmin guide 5.9: Setting up DMARC
- What is DMARC? Explanation in plain language
- Creating a DMARC record in DirectAdmin
- RFC 9989 (DMARC), in particular section 4.7 (tags) and appendix C (changes since RFC 7489)
