You’ve read the technical article on DMARCbis? Good. Now, the real question: what do I actually do with my domain?
This guide is for you, whether you’re a DNS administrator, security officer, or business owner. You’ll find a progressive action plan, concrete examples, and a pre-production checklist.
Goal: Protect your domain against spoofing without breaking legitimate email flows.
Step 1: Audit Your Current Configuration
Retrieve Your DMARC Record
Look up the TXT record _dmarc.yourdomain.com in your DNS manager, or use an online tool like senderaudit.com.
Example of a typical record:
_dmarc.example.com TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"
What to Check
| Element | Good | Needs Fixing |
|---|---|---|
p= | quarantine or reject | none (no protection) |
sp= | Explicitly defined | Absent (inherits from p=) |
pct= | Absent or removed | Present (ignored by DMARCbis) |
| SPF | Valid, ~all or -all | Absent or +all |
| DKIM | Active selector | Absent |
Test Both Discovery Methods
Important for DMARCbis: Verify that DNS Tree Walk and PSL find the same policy for your domain. A divergence can lead to unpredictable behavior depending on the receiver.
Use senderaudit.com for this test or a validator supporting RFC 9989.
The 3 Phases to Reach p=reject
Phase 1 — Monitoring (0 to 3 months)
Recommended policy:
_dmarc.example.com TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"
You activate only RUA reports without touching email delivery. This is the observation phase.
What you learn:
- Who sends from your domain (legitimate services, scripts, ESPs…)
- Pass/fail rate for SPF and DKIM
- Unknown or suspicious IPs
Example simplified report:
| Source | Volume | DKIM | SPF | Disposition |
|---|---|---|---|---|
| SendGrid (192.0.2.10) | 3,200 | Pass | Pass | None |
| Salesforce (198.51.100.1) | 800 | Pass | Fail | None |
| Unknown IP (203.0.113.5) | 50 | Fail | Fail | None |
→ Salesforce with SPF Fail: Add include:salesforce.com to your SPF.
→ Unknown IP, all Fail: Probably an attacker. Ignore for now (will be blocked when you reach reject).
Phase 1 Checklist
-
p=nonedeployed - RUA reports received and read
- False positives identified (legitimate services that fail)
- SPF and DKIM fixed for legitimate services
Phase 2 — Test Mode (3 to 6 months)
Recommended policy:
_dmarc.example.com TXT "v=DMARC1; p=reject; t=y; sp=quarantine; np=reject; rua=mailto:dmarc@example.com"
The t=y tag is the key innovation of DMARCbis. It tells receivers: “I’m testing reject, but apply quarantine or none for now.”
About np=: in most environments, a non-existent subdomain should never send mail. That is why np=reject is usually the safest default, including in test mode (t=y will effectively downgrade it to quarantine).
RUA reports will now include testing: y, confirming test mode is active.
Example RFC 9990 report:
{
"policy_published": {
"domain": "example.com",
"discovery_method": "treewalk",
"p": "reject",
"sp": "quarantine",
"np": "reject",
"testing": "y"
}
}
What to observe:
discovery_method:treewalkorpsl— which method the receiver usestesting: must beyto confirm test mode- Remaining false positives you haven’t fixed yet
Why t=y is better than the old method:
| Old practice | DMARCbis |
|---|---|
pct=0 or p=none | p=reject; t=y |
| Ambiguous: really testing reject? | Explicit: test mode confirmed |
| Ignored by RFC 9989 | Natively supported |
Phase 2 Checklist
- Policy with
t=y; p=rejectdeployed - Reports received with
testing: y - Field
discovery_methodvisible - No critical services blocked
- False positives resolved (SPF/DKIM fixed)
Phase 3 — Production (6 months and beyond)
Recommended policy:
_dmarc.example.com TXT "v=DMARC1; p=reject; sp=quarantine; np=reject; rua=mailto:dmarc@example.com"
You remove t=y and go live. Emails that don’t pass DMARC are now rejected at source.
Tag breakdown:
| Tag | Value | Effect |
|---|---|---|
p=reject | Main domain | Unauthenticated emails → rejected |
sp=quarantine | Subdomains | Suspicious emails → spam (less strict) |
np=reject | Non-existent subdomains | Emails from phantom subdomains → rejected |
Phase 3 Checklist
- Phase 2 completed without major false positives
- All third-party integrations verified (CRM, ESP, helpdesk…)
-
p=rejectdeployed (withoutt=y) - Rollback plan ready (to
p=quarantineif problems arise)
Recommended Timeline
Month 0 Month 3 Month 6 Month 12+
| | | |
Phase 1 Phase 2 Phase 3 Maintenance
p=none t=y+reject reject Monitoring
↑
DMARCbis test mode
Leverage New DMARCbis Tags
t=y: Test Without Risk
Replace this (RFC 7489, ambiguous):
v=DMARC1; p=none; pct=0; rua=mailto:...
With this (RFC 9989, explicit):
v=DMARC1; p=reject; t=y; rua=mailto:...
Receivers will know you’re testing. Reports will confirm testing: y. No surprises.
np=: Protect Non-existent Subdomains
Imagine an attacker sending from support.invoice.example.com — a subdomain that doesn’t exist in your DNS. With np=reject, these emails are rejected even if the main policy doesn’t address them.
When to use np=reject:
- ✅ Your subdomain structure is stable
- ✅ You want maximum protection
When to avoid np=reject:
- ❌ You create subdomains dynamically
- ❌ You’re in a DNS migration phase
sp=: Progressive Strategy for Subdomains
Not all your subdomains have the same DMARC maturity. sp= lets you apply a more lenient policy without touching the main policy.
Recommended strategy (progressive):
v=DMARC1; p=reject; sp=quarantine; np=quarantine; rua=mailto:...
→ Main domain: maximum protection. Subdomains: quarantine (margin for error).
Maximum strategy (everything strict):
v=DMARC1; p=reject; sp=reject; np=reject; rua=mailto:...
→ Use when all subdomains have SPF and DKIM configured.
Read and Act on RUA Reports
New Report Structure (RFC 9990)
Aggregate reports now include additional fields giving you more context:
{
"report_metadata": {
"org_name": "Gmail",
"report_id": "google-20260619",
"date_range": { "begin": "2026-06-18", "end": "2026-06-19" }
},
"policy_published": {
"domain": "example.com",
"discovery_method": "treewalk",
"p": "reject",
"sp": "quarantine",
"np": "none",
"testing": "n"
},
"records": [
{
"source_ip": "192.0.2.100",
"count": 50,
"policy_evaluated": {
"disposition": "pass",
"dkim": "pass",
"spf": "pass"
},
"auth_results": {
"spf": { "domain": "mail.example.com", "scope": "mfrom", "result": "pass" },
"dkim": { "domain": "example.com", "selector": "default", "result": "pass" }
}
}
]
}
New fields to monitor:
| Field | Expected value | If different |
|---|---|---|
discovery_method | treewalk | psl = receiver not yet migrated |
testing | y (Phase 2) or n (Phase 3) | Check if config is correct |
Interpret Results by Scenario
All PASS ✅
No action needed. Your emails are correctly authenticated.
FAIL SPF, PASS DKIM ⚠️
"dkim": "pass", "spf": "fail"
→ A service sends in your name but its IP isn’t in your SPF.
→ Action: Identify the service (reverse DNS of the IP), add include: to your SPF.
FAIL DKIM, PASS SPF ⚠️
"dkim": "fail", "spf": "pass"
→ A service sends without a valid DKIM signature. → Action: Configure DKIM on that service, or contact your ESP to enable signing.
FAIL Both ❌
"dkim": "fail", "spf": "fail"
→ Very likely an attacker spoofing your identity.
→ Action: None needed (will be blocked with p=reject). Document for audit.
Managing Backward Compatibility
Risk 1: Deprecated Tags Ignored
If you have pct=50 to test with 50% of emails, an RFC 9989 receiver ignores it and applies 100%.
Solution: Replace with t=y; p=reject.
Risk 2: PSL vs Tree Walk Divergence
For domains with complex structures (*.co.uk, nested structures), both methods may find different policies.
How to detect:
- Test your domain with PSL and Tree Walk (RFC 9989 tool)
- Watch the
discovery_methodfield in your RUA reports - If you see
pslandtreewalkwith different results → investigate
How to fix:
- Add
psd=yif your domain is a Public Suffix - Create explicit
_dmarcrecords on the affected subdomains
Risk 3: SPF HELO vs MAIL FROM
Some mail server configurations use a different HELO domain than the MAIL FROM domain. With RFC 9989, only MAIL FROM counts.
Verification: Send a test email and check the Return-Path header (= MAIL FROM). That domain must be covered by your SPF.
Complete Pre-p=reject Checklist
DNS Configuration
- SPF record valid and complete (all senders included)
- DKIM record present with active selector
- DMARC record tested with DMARCbis validator
- PSL and Tree Walk yield the same result
- Deprecated tags (
pct=,rf=,ri=) removed
Phases Completed
- Phase 1 (monitoring): minimum 3 months
- Phase 2 (test mode): minimum 3 months, with
t=y - No critical false positives identified
- RUA reports analyzed over 2-3 cycles
Third-Party Services
- All ESPs (SendGrid, Mailchimp, etc.): SPF include + DKIM configured
- CRM (Salesforce, HubSpot…): SPF include configured
- Helpdesk (Zendesk, Intercom…): DKIM configured
- E-commerce platforms (Shopify…): SPF + DKIM verified
Post-Deployment
- Active RUA monitoring (dashboard or email)
- Alert for major false positive spike
- Rollback plan to
p=quarantinedocumented
Practical FAQ
I need p=reject quickly — I can’t wait 6 months.
Accelerate the phases:
- Phase 1: 2-4 weeks (intensive monitoring)
- Phase 2: 1-2 months (with
t=y)
Don’t skip the phases — the risk is blocking your own emails. If speed is critical, go to p=quarantine first (safer than jumping straight to reject).
How do I distinguish an attacking IP from a legitimate service in reports?
- ✅ Legitimate service: Stable IP, reverse DNS with recognized service name, DKIM or SPF passing
- ❌ Attacker: Variable or unknown IP, reverse DNS absent, DKIM and SPF failing
Use nslookup <ip> and whois <ip> to identify an IP.
np=reject blocks my dynamically created subdomains. What now?
Two options:
- Switch to
np=quarantine(less strict, still protective) - Create explicit
_dmarcrecords on known subdomains:_dmarc.api.example.com TXT "v=DMARC1; p=none"
I see discovery_method: psl in my reports. Is that a problem?
Not immediately. Receivers are migrating gradually to tree walk. Verify there’s no divergence between PSL and tree walk for your domain. If results are identical, psl has no impact.
Should I activate ruf= (individual failure reports) in addition to rua=?
Probably not for most domains. rua= (aggregate reports) is sufficient for monitoring. ruf= is only useful during security investigations on targeted attacks — and generates much more data.
Conclusion
Migrating to DMARCbis is not urgent, but it is strategic. Your current policies continue to work, but the new features (t=y, np=, tree walk) give you more powerful and clearer tools.
Your action plan:
- Today: Audit your config. Remove
pct=. - This month: Switch to
p=none; rua=mailto:...if not done. - In 3 months: Switch to
p=reject; t=y(DMARCbis test mode). - In 6 months: Switch to
p=rejectproduction. - Ongoing: Read your RUA reports every week.
Need to analyze your configuration right now? Use senderaudit.com for a full audit of your domain.