Bali, Indonesia
Insights

Why Only Some Password Resets Went to Spam After Setting DMARC pct=25

October 30, 2026
0:00
A domain moves its DMARC record from p=none to p=quarantine with pct=25, and within a day support starts hearing that password reset emails are unreliable. Some users get them in the inbox. Others find them in junk. A few say the same reset request landed in the inbox once and in spam the next time. Because it is inconsistent, it tends to get treated as random spam filtering, and the actual cause gets missed. This post walks through that pattern as a post-mortem. Inconsistent results are not a sign that the sender is partly fine. They are what pct sampling looks like when one sender is failing DMARC on every message.
The visible symptom is narrow. Newsletters and staff email look normal, and only one message stream, the application's password reset and account emails, is affected. Users who cannot find the reset email request another one, which adds more volume from the same sender and more mixed reports. From the support desk this is confusing, because a user who gets one reset in the inbox reasonably concludes that email works. Asking for a screenshot of the junk copy does not help much either. The reports that help are the ones with full message headers, ideally from both an inbox copy and a junk copy at the same mailbox provider.
The first checks are routine. Was the sending IP listed on a blocklist? Did the reset template change and start looking spammy? Is the mailbox provider having a bad day? None of these explain why the problem started right after the DMARC change, or why only one stream is affected. The next step is to confirm what the domain actually publishes, since a DNS panel can show one thing while resolvers return another:
BASH
dig +short TXT _dmarc.example.com
TEXT
# Illustrative output format
"v=DMARC1; p=quarantine; pct=25; rua=mailto:[email protected]"
That matches the intended rollout, so the record is not the problem. The useful evidence is in the message headers. Comparing an inbox copy and a junk copy of the same reset email, both delivered to the same provider, shows something like this:
TEXT
# Illustrative format, inbox copy
Authentication-Results: mx.example-receiver.com;
       dkim=pass [email protected];
       spf=pass [email protected];
       dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=example.com

# Illustrative format, junk copy
Authentication-Results: mx.example-receiver.com;
       dkim=pass [email protected];
       spf=pass [email protected];
       dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=QUARANTINE) header.from=example.com
Both copies fail DMARC. The only difference is dis, the disposition the receiver actually applied. One message was put in quarantine and the other was let through. The exact field names vary by provider, and some report the outcome in a separate field or a different header, so it is worth learning how each major provider you send to writes this. If reading these lines is new to you, Reading Authentication-Results Headers to Fix DMARC Alignment covers the fields in more detail.
This is the part that clears up the confusion. The pct tag tells receivers what percentage of messages that fail DMARC should have the policy applied. Under the original DMARC specification, failing messages that are not selected get the next less strict policy, so with p=quarantine the unselected ones are treated as p=none and delivered normally, subject to whatever spam filtering the receiver does anyway. The sampling is per message, and the receiver decides. It does not split senders into good and bad groups. If a sender fails DMARC on every message, then with pct=25 roughly a quarter of its failing mail is quarantined and the rest gets through. The exact share depends on the receiver, and receivers are not required to hit the number precisely. That is why the same user can get one reset in the inbox and the next one in junk. The headers also show why every reset fails. SPF passes, and DKIM passes, but both pass for mailer-provider.net, not for example.com. DMARC does not just ask whether SPF or DKIM passed. It asks whether at least one of them passed for a domain that aligns with the visible From: header domain. Here the Return-Path (the envelope sender used for bounces) belongs to the provider, and the DKIM signature uses the provider's d= domain. Neither aligns with example.com, so DMARC fails every time. What usually happens is that the reset emails were set up long ago, through a transactional email service, an SMTP plugin, or the app's own mail library, and nobody connected the provider's authentication settings to the company domain. Under p=none that never caused a visible problem, so it went unnoticed. Aggregate reports, the XML files sent to the rua address, confirm this at scale. Records for the provider's sending IPs show DKIM and SPF evaluated as fail at the policy level even though the underlying auth results pass. Some reporters also add an override reason of sampled_out for failing messages that were let through because of pct. A sender that shows up with a mix of quarantine dispositions and sampled_out is exactly the stream you are looking for.
The most important decision at this point is what not to do. Raising pct to 50 or 100 on schedule would push the quarantine rate for reset emails from some of the time to nearly all of the time. Moving to p=reject would cause those messages to be refused rather than junked. There are two reasonable short-term options, and which one fits depends on how fast the sender can be fixed. If the provider settings can be corrected the same day, keep the record as it is and fix the alignment. The impact is limited and stops as soon as signed, aligned mail starts flowing. If the fix depends on someone else, such as a developer, an agency, or a vendor account nobody has the login for, it can be worth temporarily stepping back to p=none so reset emails stop landing in junk while the work happens. That gives up enforcement for a while, which is a real trade-off for a domain that might be spoofed, so treat it as a short pause with a clear owner, not a new default. In both cases, tell support what is going on. A short note saying that reset emails may land in junk, to check the spam folder, and that a fix is in progress cuts down on repeat requests, and repeat requests only add more failing mail.
The lasting fix is to make the transactional sender authenticate as your domain. With most email service providers this means two things, though the exact steps and record names depend on the provider:
  1. Custom DKIM: publish the provider's DKIM key under your domain so messages are signed with d=example.com or a subdomain of it.
  2. Custom Return-Path: point a bounce subdomain such as bounce.example.com at the provider, usually via a CNAME, so the envelope sender is under your domain and SPF can align.
With DMARC's default relaxed alignment, a subdomain like bounce.example.com aligns with a From: of example.com, because both share the same organizational domain. DKIM alignment alone is enough to pass DMARC. Aligned SPF is a useful second path, and it helps in cases where a DKIM signature does not survive. After the change, send a test reset to an outside mailbox and read the headers again. You want dmarc=pass with the DKIM header.i or header.d under your own domain. Then watch the aggregate reports for that sender over several days. It should move from failing to passing across all receivers, not just the one you tested. The bigger lesson is about the rollout process. One forgotten sender got through monitoring because nobody went through the aggregate reports source by source before turning on enforcement. Before each pct increase, it helps to list every source that sends as the domain and confirm it is aligned, including app servers, CRMs, helpdesk tools, billing systems, and anything a developer set up years ago. What to Audit Before Switching DMARC Policy from None to Reject goes through that checklist. Also note that newer revisions of the DMARC standard move away from pct toward a simpler testing flag, so check how your target receivers handle it rather than assuming fine-grained percentages will always work. The practical takeaway: when some messages from one sender reach the inbox and others land in junk right after a pct rollout, assume that sender is failing DMARC every time and the percentage is just hiding it. Pull headers from both an inbox copy and a junk copy, compare dmarc= and the disposition, and fix the alignment before you raise pct.