Skip to main content
cd ../config-traps
risk/register/dmarc-pct-unset-caps-enforcement-at-zero.html
DNS Email Authenticationhigh severityDNS

DMARC pct Left Unset Silently Caps Enforcement at Zero Despite a p=reject Policy

Severity
high
Reviewed
8 Sept 2026
Remediation
~20 minutes
Overview

A DMARC record using p=reject with pct omitted relies on a specification default that some mail paths do not honour identically to an explicit value, leaving spoofed mail delivered while aggregate reports look clean.

Operational summary

At a glance

Symptom
The DMARC record for a domain reads v=DMARC1; p=reject; rua=mailto:dmarc-agg@example.com; fo=1.
Likely cause
The root cause is a combination of (1) an implicit default value (pct absent, defaulting to 100 per specification) that is not independently verified…
Impact
Spoofed mail using the exact protected domain continued to be delivered to a subset of recipients during the affected window, undermining the anti-spoofing control the domain owner believed…
Verification signal
Validation requires confirming both the published record and the observed enforcement behaviour, not the record text alone.
Safe correction
The correction is to make policy application explicit and independently verifiable rather than relying on the specification default.
Rollback or recovery
If the explicit pct=100 change causes unexpected legitimate mail rejection (for example, from a previously undiscovered forwarding path that was relying on lenient enforcement), revert the TXT record…

Symptom

The DMARC record for a domain reads v=DMARC1; p=reject; rua=mailto:dmarc-agg@example.com; fo=1. Aggregate (RUA) reports arrive daily and show authentication passing for legitimate senders. Despite this apparently healthy configuration, spoofed mail using the exact domain in the From header continues to reach recipient inboxes at several receiving organisations, and the DMARC aggregate reports show disposition=none for the spoofed traffic instead of disposition=reject.

False Assumption

The operator assumed that omitting the pct tag is equivalent to pct=100, meaning the reject policy applies to all mail failing DMARC alignment. RFC 7489 does define the default value of pct as 100 when absent, so this assumption is textually correct for a fully RFC-compliant validator. The deceptive failure is that some receiver implementations historically applied partial or inconsistent rounding/sampling logic to policy application even at the documented default, and more commonly, intermediate mail infrastructure (forwarding services, mailing list expanders, or secondary MX relays) evaluates DMARC prior to final delivery and does not consistently honour p=reject when pct is absent versus explicitly set. The visible symptom (clean aggregate reports) masks the real gap because RUA reports reflect what the reporting receiver observed and decided, not what every receiver in the delivery path actually enforced.

Root Cause

The root cause is a combination of (1) an implicit default value (pct absent, defaulting to 100 per specification) that is not independently verified against receiver behaviour, and (2) reliance on RUA aggregate data alone as proof of enforcement. Aggregate reports describe the evaluating receiver’s own policy decision at the point it generated the report; they do not prove that every mail path applying the domain’s DMARC record enforced p=reject at the default pct. Some large receivers apply reject policy gradually even when pct is absent, treating an explicit pct=100 differently in internal rollout logic than an unset tag, despite both being specification-equivalent. The domain owner had no visibility into this internal distinction because the published record and the specification text both suggested full enforcement was already active.

Impact

Spoofed mail using the exact protected domain continued to be delivered to a subset of recipients during the affected window, undermining the anti-spoofing control the domain owner believed was fully active. Because RUA reports showed passing alignment for legitimate mail and no volume of rejected spoofed mail was visible in that same feed (spoofed mail from external non-cooperating senders does not always generate reports back to the domain owner), the gap was not discoverable from DMARC reporting data alone. Forensic reports (RUF), where configured, or third-party phishing-simulation and delivery testing are required to observe the gap directly.

Diagnosis

Confirm the exact tags present in the live DNS TXT record at _dmarc.example.com, not the record as originally drafted or documented internally. Distinguish the specification default from verified receiver behaviour: query the live record, note whether pct is present, and then run a controlled spoof test from an isolated non-production sending path against multiple receiving mailbox providers to observe actual disposition, not just the policy tag.

Diagnostic commands

Run these from an isolated workstation or lab host. None of these commands change any DNS record or mail flow; all are read-only queries.

dig +short TXT _dmarc.example.com
dig +short TXT _dmarc.example.com @1.1.1.1

Compare the two results. A mismatch between authoritative and public resolver answers indicates propagation lag or a secondary provider serving stale data, which is itself a contributing factor worth recording before drawing conclusions from the record content.

Correction

The correction is to make policy application explicit and independently verifiable rather than relying on the specification default. Publish an explicit pct=100 tag alongside p=reject so the enforcement level cannot be misread by any downstream tooling, monitoring dashboard, or receiver-side implementation detail that treats absent and explicit values differently. This is a state-changing DNS record update.

_dmarc.example.com. IN TXT "v=DMARC1; p=reject; pct=100; rua=mailto:dmarc-agg@example.com; ruf=mailto:dmarc-forensic@example.com; fo=1"

Apply this change in a staging or delegated test subdomain first if the production zone supports it, or schedule the production change during a low-volume mail window with monitoring in place before and after the change.

Validation

Validation requires confirming both the published record and the observed enforcement behaviour, not the record text alone. After publishing the explicit pct=100 value, re-query the record from at least two independent resolvers to confirm propagation, then monitor incoming RUA aggregate reports over a minimum of seven days to confirm disposition=reject appears for any deliberately induced misaligned test message sent from an authorised test sender that intentionally fails SPF and DKIM alignment.

Rollback

If the explicit pct=100 change causes unexpected legitimate mail rejection (for example, from a previously undiscovered forwarding path that was relying on lenient enforcement), revert the TXT record to the prior known-good value captured before the change, or temporarily set p=quarantine with pct=100 as a lower-impact interim step while the affected mail path is identified. Keep the pre-change record text in change-management documentation before applying any DNS edit so the rollback value is exact rather than reconstructed from memory.

Prevention

Treat DMARC aggregate reports as evidence of what cooperating receivers observed, not as proof of complete enforcement across every mail path. Always publish tags explicitly rather than relying on specification defaults for security-relevant values, since explicit values remove ambiguity for every downstream consumer of the record, including monitoring tools, auditors and receiver implementations that may not treat defaults consistently. Schedule periodic controlled spoof testing against major receiving providers as a standing check, independent of RUA volume, and record the DMARC record text alongside every change ticket so the rollback state is always known precisely.

03

Apply the safer control

Before you change production

Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.

Fix commands and configuration

v=DMARC1; p=reject; rua=mailto:dmarc-agg@example.com; fo=1
disposition=none
disposition=reject
04

Verify, roll back or escalate

Verify

Validation requires confirming both the published record and the observed enforcement behaviour, not the record text alone.

Rollback

If the explicit pct=100 change causes unexpected legitimate mail rejection (for example, from a previously undiscovered forwarding path that was relying on lenient enforcement), revert the TXT record to the prior known-good value captured before the change, or temporarily set…

Escalate

Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.

After remediation

Further reading stays below the corrective workflow and is selected by platform, category and shared technical keywords.

Discover more

Connected KBY resources