DMARC Coverage — the pct Tag
DMARC coverage — the pct tag
The pct= tag tells receivers what percentage of failing messages to apply the policy to. Default is 100. The tag exists for one reason: gradual rollout. It lets you turn on p=quarantine or p=reject for a fraction of mail, watch the results, and ramp up.
Cathedra checks the value and warns when coverage is partial. The finding is mechanical and the use case is operational.
What the tag does
The DMARC record:
v=DMARC1; p=quarantine; pct=10; rua=mailto:dmarc@isidoregroup.com
pct=10 means: when a message fails alignment, apply p=quarantine to 10% of failures. The other 90% are treated as if the policy were p=none — observed and reported, but not acted on.
The selection is randomized per message by the receiver. Over a large enough sample, roughly 10% of failures land in spam and 90% are delivered normally.
A few useful properties:
pct=applies to failing messages. A passing message is unaffected.- The fallback for the un-acted-on percentage is one policy step down.
p=quarantine; pct=10quarantines 10% and treats 90% asp=none.p=reject; pct=10rejects 10% and quarantines 90% (one step down from reject). pct=does nothing underp=none, because there is no policy to scale.
What Cathedra reports
DmarcRecordCheck.php reads the tag, defaults to 100 if absent, and checks two conditions:
- The policy is
quarantineorreject(notnone). pct < 100.
If both are true, Cathedra emits:
| Field | Value |
|---|---|
| status | warning |
| severity | low |
| finding | “DMARC pct={value}%. Policy only applies to {value}% of failing messages.” |
| recommendation | “Increase pct to 100 once you have validated your mail streams.” |
Severity is low. Cathedra recognizes this as a transitional state, not a misconfiguration. The warning is there to make sure no one forgets to finish the ramp.
When pct=100 or the tag is absent, no separate finding appears — the policy check alone produces the result.
When you would actually use pct
There are exactly two practical reasons to publish a partial pct.
1. Mid-ramp on a large client.
You moved from p=none to p=quarantine last week. Reports show alignment is mostly clean, but you want to limit blast radius while the last few legitimate senders shake out. pct=10 for two weeks, then pct=25, then pct=50, then pct=100. By the time you reach 100%, you have observed every category of message at the new policy level and surfaced any remaining alignment failures.
2. Risk-managed move from quarantine to reject.
The client is at p=quarantine; pct=100 and stable. Moving to p=reject; pct=100 in one step is the right answer if reports are clean for several weeks. If they are not — if some mail stream still occasionally fails — p=reject; pct=10 is a way to start rejecting a slice and watching whether anyone complains, without nuking the other 90% if you missed a sender.
Outside those two cases, partial pct is noise. A long-standing pct=50 is almost always a forgotten ramp from years ago.
The trap to avoid
The most common misuse of pct= is treating it as a permanent dial. “We have p=reject; pct=50 because we are not ready for 100% yet.” This is a tell — the client has not actually solved their alignment problem; they have built a workaround that lets half their phish through.
The right answer in that case is to step back to p=quarantine; pct=100 (full coverage at a softer policy) rather than fractional reject. Quarantine at 100% is operationally safer than reject at 50%, because reject at 50% still bounces real mail half the time.
When you see partial pct on a long-standing record, ask: when was this ramp supposed to finish? If the answer is “we don’t know” or “a year ago,” that is a remediation item.
A worked example
A client at p=quarantine; pct=10 for four weeks. Aggregate reports show:
- 12,400 messages passed alignment (legitimate mail flowing normally).
- 380 messages failed alignment. Of those, the receiver records show ~10% (~38) were quarantined and ~90% (~342) were delivered.
- The 380 failures break into three sources: a marketing automation tool not signing with DKIM, a CRM not aligned on SPF, and a residual ~50 messages from sources Cathedra cannot identify.
Next step: fix the marketing and CRM alignment (publish a CNAME for the tool’s DKIM key, or change the tool’s envelope domain). Then move to pct=25. Repeat reading reports for two weeks. Then pct=50. Then pct=100. Then plan the move to p=reject.
Each step is a discrete decision based on what the reports show. Do not promote on a schedule; promote on evidence.
What you should remember
pct=scales how much of failing mail gets the policy. Default is 100.- Cathedra warns at
pct < 100with quarantine or reject, severity low. Finding: “DMARC pct={value}%. Policy only applies to {value}% of failing messages.” - Partial pct is for transition. Long-standing partial pct is a forgotten ramp.
- Quarantine at 100% is safer than reject at 50%. If a client cannot reach reject, step back to full quarantine rather than fractional reject.
- Promote on evidence — reports clean — not on calendar.
Cathedra alignment: DmarcRecordCheck.php — the second finding the check produces, when pct<100 with quarantine or reject
