Updated for RFC 9989 (May 2026). RFC 9989 removed the pct tag and introduced t=y as the recommended way to stage enforcement. RFC 9989 §7.4 also revised the long-standing "everyone should aim for p=reject" guidance: see Should you publish p=reject? below. For background, read the RFC 9989/9990/9991 explainer.
The three DMARC policy stages
DMARC defines three enforcement levels. Each one tells receiving mail servers what to do with messages that fail authentication. The progression is monitor, quarantine, and (where appropriate) reject.
p=none (monitoring only)
The receiving server delivers the message regardless of whether it passes or fails DMARC. You still receive aggregate and failure reports, but no enforcement action is taken. This is where every DMARC deployment starts.
p=quarantine (partial enforcement)
Messages that fail DMARC are routed to the recipient's spam or junk folder. The message is not lost, but it is flagged as suspicious. This gives you a safety net. If a legitimate source is misconfigured, users can still find the message in spam and report the problem. RFC 9989 §7.4 treats p=quarantine as the appropriate end state for most domains that host human users.
p=reject (full enforcement)
The receiving server rejects the message outright during the SMTP transaction. The sender gets a bounce. The recipient never sees the message at all. This is the strongest protection against spoofing and phishing, but RFC 9989 §7.4 narrows the audience for which it is appropriate. See Should you publish p=reject? below before adopting it.
Skipping from p=none directly to enforcement is a common mistake that causes legitimate mail loss. Marketing emails, transactional messages, CRM notifications, and helpdesk replies can all fail silently if they have not been properly authenticated. The phased approach described below eliminates that risk.
Should you publish p=reject?
For most of the last decade, the conventional advice has been: aim for p=reject as the final state. RFC 9989 §7.4 (May 2026) pushed back on that advice, and the language is direct.
From RFC 9989 §7.4:
"It is therefore critical that domains that host users who might post messages to mailing lists SHOULD NOT publish Domain Owner Assessment Policies of 'p=reject'."
"In the absence of other knowledge and analysis, Mail Receivers MUST treat such failing mail as if the policy were 'p=quarantine' rather than 'p=reject'."
The reasoning is the indirect-mail-flow problem. When a user posts to a mailing list, the list resends the message with the original From: header intact. SPF breaks (the list's IP is not in the user's SPF record), and DKIM often breaks too (the list rewrites the subject or adds a footer). Under p=reject, the list's other subscribers stop receiving the message, the list software interprets the bounces as a dead address, and it auto-unsubscribes them.
A practical way to decide:
- Publish
p=rejecton transactional or marketing-only domains where no human posts mail (bank notification domains, e-commerce receipt domains, dedicatedmail.brand.comsubdomains). The conformance section of RFC 9989 §8 still allowsp=rejectin these cases, especially when DKIM-aligned mail is in place and you are not relying solely on SPF. - Publish
p=quarantineon domains that host employee or customer mailboxes, where a human might subscribe to an external mailing list. Usesp=rejectfor non-sending subdomains as additional protection.
The short version: if real people read mail at addresses on this domain, target p=quarantine. If only systems send from this domain and nobody posts from it, p=reject may be appropriate.
Phase 1: publish p=none and start monitoring
Your first DMARC record should enable monitoring without any enforcement. Publish the following TXT record at _dmarc.yourdomain.com:
v=DMARC1; p=none; rua=mailto:[email protected]; ruf=mailto:[email protected]
The rua tag tells receivers where to send aggregate reports (XML summaries of authentication results). The ruf tag requests failure reports (individual failure details, formerly called forensic reports). Not all receivers send them, but aggregate reports are widely supported.
How long to stay at p=none
Minimum: 2 to 4 weeks. Ideal: 4 to 8 weeks. The goal is to capture every sending pattern your domain uses. Some senders only fire once a month (newsletters, quarterly financial reports, automated billing summaries). If you move to enforcement before capturing these, you will miss them and they will break.
What to look for in reports
Your aggregate reports will show every IP address that sent mail using your domain in the From header. For each source, you need to answer three questions:
- Is this a legitimate sender? (Your mail server, your ESP, your CRM, a partner sending on your behalf)
- Does it pass SPF? (The sending IP is listed in your SPF record, and the Return-Path domain aligns with your From domain)
- Does it pass DKIM? (The message is DKIM-signed with a
d=value that matches your From domain)
Build a sending source inventory
Create a spreadsheet or document listing every legitimate sending source. For each one, record:
- Source name: e.g., Mailchimp, Salesforce, your on-premise Exchange server
- Sending IPs: the IP addresses or ranges shown in your reports
- SPF status: pass or fail
-
DKIM status: pass or fail, and the
d=domain used - Alignment: does SPF or DKIM align with your From domain?
Your target before moving to the next phase: 95%+ DMARC pass rate across all legitimate sources. Use the DMARCTrust dashboard to track this automatically.
Phase 2: reading reports and fixing sources
How to interpret aggregate reports
Aggregate reports are XML files. Each report contains one or more <record> elements. Each record describes a group of messages from a single source IP with identical authentication results.
The key elements inside each record:
-
<source_ip>: the IP address that sent the messages -
<count>: the number of messages in this group -
<policy_evaluated>: the DMARC verdict. Contains<dkim>(pass/fail),<spf>(pass/fail), and<disposition>(none, quarantine, or reject) -
<auth_results>: the raw SPF and DKIM results before alignment is applied
The difference between <policy_evaluated> and <auth_results> matters. A message can pass raw SPF (the IP is authorized) but fail DMARC SPF alignment (the Return-Path domain does not match the From domain). This is one of the most common causes of DMARC failure for third-party senders. For a detailed explanation of the DMARC record structure, see the DMARC tags guide.
Common sources that fail
- Old marketing tools still sending as your domain but using their own Return-Path and no custom DKIM
-
Forgotten subdomain services like
support.yourdomain.comorbilling.yourdomain.comwith no SPF/DKIM setup - Partners and vendors sending on your behalf (recruitment platforms, payroll systems, e-commerce platforms)
- Legacy on-premise servers with outdated configurations
- Internal test environments that send email using production domain names
Fix each failing source
For each source that fails DMARC, you have two paths:
-
Configure custom DKIM: ask the vendor to sign messages with a DKIM key where
d=yourdomain.com. This is the preferred approach because DKIM survives forwarding. Most modern ESPs support this. -
Configure a custom Return-Path: set the bounce address (envelope sender) to a subdomain you control, like
bounce.yourdomain.com, and include the vendor's sending IPs in that subdomain's SPF record. This achieves SPF alignment.
Ideally, configure both. If you can only do one, prioritize DKIM. It is more resilient.
Subdomains: lock these down before you tighten the parent
Most spoofing attempts target subdomains, not the apex. Set sp= and np= on the parent record before you move the parent policy above p=none. This gives you structural protection independent of how quickly you can clean up your sending sources.
-
sp=quarantineorsp=rejectin the parent record: sets a default policy for existing subdomains. Use this if your subdomains do not send mail, or you have already cleaned them up. -
np=rejectin the parent record (new in RFC 9989): sets a policy for subdomains that do not exist in DNS. This asks receivers to reject spoofed names likesupport.yourdomain.comthat you never created. Use it when you do not intentionally send mail from DNS-empty names; it has no impact on normal subdomains that actually exist. - A separate
_dmarc.subdomain.yourdomain.comrecord: gives a specific subdomain its own policy when it diverges from the parent.
A reasonable parent record while still cleaning up the apex is:
v=DMARC1; p=none; sp=quarantine; np=reject; rua=mailto:[email protected]
Phase 3: move to p=quarantine using the t=y test mode flag
Once your sending source inventory is complete and your pass rate is above 95%, you are ready for soft enforcement. RFC 9989 introduced the t tag (test mode) for this transition. With t=y, you declare the policy you intend to enforce while asking receivers to apply the next-lower policy instead. So p=quarantine; t=y tells receivers to treat the message as if p=none. You still get reports, but enforcement is held back.
Publish the test-mode record for 1 to 2 weeks:
v=DMARC1; p=quarantine; sp=quarantine; np=reject; t=y; rua=mailto:[email protected]
Then drop t=y to start enforcing:
v=DMARC1; p=quarantine; sp=quarantine; np=reject; rua=mailto:[email protected]
Why not pct=25 → 50 → 100? Because RFC 9989 removed the pct tag in May 2026 (see Appendix A.6). The working group found that pct was usually applied accurately only when set to 0 or 100. With intermediate values, implementations differed widely on what they actually did, which made gradual rollout less reliable than it looked. The t=y flag is coarser but predictable.
What to monitor at p=quarantine
- User complaints: "My emails are going to spam." This usually indicates an unauthenticated source you missed.
- Aggregate reports: look for unexpected failures. New sources may appear that were not active during your monitoring period.
- Bounce rates: a sudden increase in bounces from a specific sending service suggests a configuration problem.
-
discovery_methodin reports: RFC 9990 added this field to aggregate reports. Values arepslortreewalk. It tells you whether the receiver migrated to the new policy-discovery algorithm.
Stay at p=quarantine for at least 2 weeks with clean reports before deciding whether to move further. Many domains stop here. See Should you publish p=reject? above.
Rolling back
If something goes wrong, set t=y to dampen enforcement, or change the policy back to p=none. DNS propagation typically takes minutes to a few hours. During propagation, some receivers will still apply the old policy. This is expected and temporary.
Phase 4 (only if appropriate): move to p=reject
This stage is appropriate only for domains that do not host users who post to mailing lists, typically transactional or marketing-only domains. Read Should you publish p=reject? above before continuing. For mixed-use domains where humans receive and post mail, p=quarantine is the recommended terminal state.
If your domain qualifies, do a 1 to 2 week dry run with t=y first. RFC 9989 §A.6 explicitly designed t=y for this case: at p=reject; t=y, receivers apply p=quarantine instead, so you can observe the impact before committing.
v=DMARC1; p=reject; sp=reject; np=reject; t=y; rua=mailto:[email protected]
When reports are clean, remove t=y:
v=DMARC1; p=reject; sp=reject; np=reject; rua=mailto:[email protected]
Expected impact
Legitimate forwarded mail can still be affected even on a clean transactional domain. When a message is forwarded through an intermediary (mailing list, email forwarding service), SPF breaks because the sending IP changes. If the intermediary also modifies the message body or headers, DKIM breaks too. RFC 9989 §7.4 now requires receivers to treat p=reject as p=quarantine in the absence of other information, which reduces but does not eliminate the impact. For details and mitigation strategies, see the forwarding and ARC troubleshooting guide.
Ongoing vigilance
New services, new employees, mergers, and acquisitions can introduce new sending sources at any time. A marketing team signs up for a new campaign tool. An HR department starts using a new recruiting platform. Each of these can start sending mail as your domain without proper authentication. Keep monitoring.
Pre-enforcement checklist
Before you remove t=y and start enforcing (whether at quarantine or reject), verify every item on this list:
- You have decided which terminal policy is appropriate. Re-read Should you publish p=reject? if you are unsure.
- All known sending sources authenticate with SPF or DKIM (or both). RFC 9989 §8 requires DKIM specifically if your terminal policy is
p=reject. Do not rely solely on SPF in that case. - DKIM alignment is confirmed for every ESP. The DKIM
d=value matches your From domain. - Your SPF record is within the 10-lookup limit. Use
dig TXT yourdomain.comand count theinclude:,redirect=,a:, andmx:mechanisms. - Subdomain policy is intentional:
sp=quarantineorsp=rejectfor existing subdomains when appropriate, andnp=rejectfor non-existent names you want to fail closed. - You have been at the chosen policy with
t=yfor at least 1 to 2 weeks with a 99%+ pass rate. - The impact on forwarded mail has been assessed and communicated to affected users.
- All stakeholders have been notified: marketing, HR, customer support, IT, finance, and any team that sends email externally.
Use the DMARCTrust DMARC checker to verify your current record and authentication status before making the change.
Rollback procedure
If legitimate mail is being rejected after moving to p=reject, follow this procedure:
-
Step 1: downgrade to quarantine immediately. Change your DMARC record to
p=quarantine. This stops messages from being dropped. They will go to spam instead, which is recoverable. - Step 2: identify the failing source. Check your DMARC aggregate reports for the source IP that is failing authentication. Cross-reference it with your sending source inventory.
- Step 3: fix authentication. Configure DKIM or SPF for the failing source. If it is a third-party vendor, contact their support team for custom domain authentication setup.
-
Step 4: verify DNS propagation. After updating DNS records, confirm the change has propagated:
dig TXT _dmarc.yourdomain.com dig TXT yourdomain.com # Check SPF dig TXT selector._domainkey.yourdomain.com # Check DKIM -
Step 5: return to your terminal policy. Once the fix is confirmed in your aggregate reports (allow 24 to 48 hours for reports to arrive), move back to your terminal policy — either
p=quarantine(for domains hosting human users) orp=reject(for transactional/marketing-only domains). Consider a 1 to 2 week dry run witht=ybefore re-enforcing.
Never go straight back to p=none unless there is a critical, business-wide impact. Dropping to p=none removes all enforcement and re-exposes your domain to spoofing. Quarantine is almost always sufficient as an intermediate step.
Timeline summary
The following timeline assumes a medium-complexity domain with 5 to 15 sending sources. Simpler domains can move faster. Domains with dozens of sending sources or complex subdomain structures may need longer at each stage. The Phase 4 row is optional — see Should you publish p=reject?.
| Week | DMARC record | Action |
|---|---|---|
| 1-2 | p=none; np=reject |
Publish DMARC record with rua and (optionally) ruf tags. Add np=reject when you want non-existent subdomains to fail closed. Start receiving reports. |
| 3-8 | p=none; sp=quarantine; np=reject |
Identify all legitimate sending sources. Fix SPF and DKIM for each one. Build your sending source inventory. Target 95%+ pass rate. Tighten sp= to quarantine once subdomains are clean. |
| 9-10 | p=quarantine; t=y; sp=quarantine; np=reject |
Test mode for quarantine. Receivers treat the message as p=none while you observe. |
| 11+ | p=quarantine; sp=quarantine; np=reject |
Drop t=y to begin quarantine enforcement. Hold for at least 2 weeks with 99%+ pass rate. For most domains that host human users, this is the terminal state. |
| 13-14 (optional) | p=reject; t=y; sp=reject; np=reject |
Only if your domain qualifies for p=reject (transactional/marketing-only). Test mode for reject — receivers apply quarantine instead. |
| 15+ (optional) | p=reject; sp=reject; np=reject |
Drop t=y for reject enforcement on qualifying domains. |
| Ongoing | (your terminal policy) | Monitor reports weekly. Audit new sending sources. Review after onboarding any new tool or vendor. Watch the discovery_method field in aggregate reports as receivers migrate to the DNS Tree Walk algorithm. |
Prevention and ongoing monitoring
Email infrastructure changes after you reach enforcement. New tools get adopted, vendors change their sending infrastructure, and employees set up services that send email as your domain without telling IT.
Set up automated alerts
Configure DMARCTrust alerts to notify you when your authentication pass rate drops below a threshold. A sudden spike in DMARC failures usually means a new or changed sending source.
Weekly report review
Even with alerts, review your aggregate reports at least once a week. Look for:
- New source IPs that you do not recognize
- Changes in volume from known sources (could indicate a compromised account)
- Failures from sources that previously passed (could indicate a DNS or key rotation issue)
Vendor onboarding process
Every time your organization adopts a new tool that sends email, add an authentication step to the onboarding process:
- Ask the vendor for their SPF include mechanism and DKIM setup instructions
- Configure custom DKIM with
d=yourdomain.com(preferred) or add their IPs to your SPF record - Send a test message and verify it passes DMARC using the DMARCTrust checker
- Add the vendor to your sending source inventory
Document your email sending inventory
Maintain a living document that lists every service authorized to send email as your domain. Include the service name, purpose, SPF/DKIM configuration status, and the team responsible. Review it quarterly. This document saves hours during incident response and when onboarding new IT staff.
Next steps
If you are just starting your DMARC deployment, begin with the introduction to DMARC to understand the fundamentals. Use the DMARC generator to create your initial p=none record, then follow the phases described above.
If you are already at p=quarantine or p=reject and experiencing authentication failures, the other troubleshooting guides cover specific failure types: