What p=reject actually does
A DMARC policy is an instruction to receiving mail servers about what to
do with a message that uses your domain in the visible From header and
fails DMARC. p=none says do nothing beyond reporting. p=quarantine
says treat it as suspicious, which in practice means the spam folder.
p=reject says refuse it.
Most receivers that honour p=reject do so at the SMTP transaction with
a permanent 5xx response, so the sending server does not queue and
retry — the message is gone on the first attempt. Some receivers accept
the message and discard it afterwards, in which case there is not even a
bounce for the sender to notice. Either way the mailbox owner never sees
it, and you, the domain owner, get no real-time signal. What you get is a
row in the next aggregate report:
<row>
<source_ip>203.0.113.27</source_ip>
<count>142</count>
<policy_evaluated>
<disposition>reject</disposition>
<dkim>fail</dkim>
<spf>fail</spf>
</policy_evaluated>
</row>
That is the crux of the risk. Reject is a policy applied by other people’s servers to mail you may not know you are sending, and the feedback loop runs a day behind, at best.
“Fails DMARC” means “not aligned”, not “not yours”
It is worth being precise about which mail gets rejected. DMARC does not
reject mail that is fraudulent; it rejects mail that is not aligned
with your domain. A message passes DMARC if SPF or DKIM passes and the
domain that passed matches the From domain. A perfectly legitimate
invoice sent by your billing platform, authenticated cleanly against the
platform’s own domain, fails alignment against yours — and under
p=reject that invoice is refused exactly as if it were a phish. The
worked example in
how SPF and DKIM can both pass while DMARC fails
shows the headers this produces.
So the question before moving to reject is not “is anyone spoofing us?” It is “does every system that puts our domain in a From header authenticate in a way that aligns with it?” Every sender you have not found is a sender you have not aligned, and every sender you have not aligned is a sender you are about to block.
The senders that get missed
Ask an IT team to list what sends mail as their domain and the answer is usually the mail platform, the marketing ESP, and one or two SaaS products. The aggregate reports almost always show more. The categories that reliably turn up late:
- Transactional SaaS with a “send as your domain” setting. CRM,
helpdesk, HR and payroll, billing and invoicing, e-signature, project
management, recruiting, booking and scheduling. Each of these was
configured by whichever team bought it, often years ago, and each
sends from
Fromaddresses on your domain unless it was told otherwise. - Devices. Multifunction printers doing scan-to-email, alarm and building-management systems, UPS and network hardware sending alerts. These relay through whatever SMTP host was reachable when they were installed, frequently with no authentication at all.
- Servers and cron jobs. Application error mail, backup reports,
monitoring alerts, anything that calls
sendmailon a box that has been running since before anyone on the current team joined. - Vendors sending on your behalf. An outsourced payroll provider, a survey vendor, a debt-collection agency, a print-and-post service — anyone contracted to email your customers “from” you. See sending DMARC-compliant mail on behalf of others for how that is supposed to be set up, and why it often isn’t.
- Subsidiaries, acquisitions and regional offices running their own mail platform, often on a subdomain (below).
- Low-frequency senders. Quarterly statements, annual renewal notices, end-of-financial-year mail, an awards programme that sends once a year. A month of clean reports says nothing about a system that sends in March.
The report data is the inventory, and it only counts what has actually
sent during the observation window. That is why the advice in
publishing a DMARC record is to sit at
p=none for a full business cycle rather than a couple of weeks: the
sender you are worried about is the one that has not sent yet.
Subdomains inherit the policy
A p=reject on example.com applies to every subdomain that does not
publish its own DMARC record, unless the organisational record sets a
different sp (policy for existing subdomains). Under DMARCbis it also
applies to non-existent subdomains unless np is set. So the moment
example.com goes to reject, mail from alerts.example.com,
crm.example.com and mail.au.example.com is subject to the same
policy — whether or not anyone knew those hostnames were sending.
This is where an incomplete inventory does the most damage, because subdomain senders are exactly the ones that were set up outside the main mail platform. Two defensive options while the inventory is still running:
v=DMARC1; p=reject; sp=quarantine; np=reject; rua=mailto:dmarc-reports@example.com
Enforce on the organisational domain, quarantine rather than reject on
existing subdomains until their senders are aligned, and reject outright
on subdomains that do not exist (nothing legitimate sends from those).
Or publish a separate _dmarc.alerts.example.com record with its own
policy for any subdomain whose senders are still being worked out.
The DMARC Inspector shows the p and sp a
published record resolves to, including the inherited default.
The SPF trap: fixing one sender can break every sender
The usual way to align a newly discovered sender is to add it to SPF.
SPF is limited to ten DNS lookups per evaluation, and every include:
for a SaaS platform costs one or more of them. Adding the fifth or sixth
vendor is regularly what pushes a record over the limit, at which point
SPF returns permerror — for every message, from every sender, not
just the one you added.
Under p=none that is an inconvenience visible in reports. Under
p=reject, any sender that relied on SPF for alignment (which is most of
them, because DKIM alignment through a third party takes a custom
selector that many were never given) now fails DMARC and is refused. One
DNS edit, made to fix a sender, has rejected all of them.
The SPF Check tool counts lookups against the limit for the record as it is actually published. Run it before and after every SPF change once you are at enforcement, and prefer DKIM alignment for every sender that can support it, so that SPF’s fragility stops being the thing your mail depends on.
Aligned today is not aligned permanently
Identifying a sender and aligning it once is not the end. Senders drift:
- A vendor rotates its DKIM keys and expects you to update the CNAMEs
it gave you. If they were
TXTcopies of the key rather than CNAMEs to the vendor’s own records, the signature stops validating. - A platform changes its sending IP ranges and its
include:no longer covers them. - Someone in another team enables a new “send from our domain” feature in a tool that was previously sending from the vendor’s domain.
- A subdomain’s dedicated DKIM selector is cleaned up by someone tidying the DNS zone.
At p=none or p=quarantine, each of these shows up as a dip in
alignment for a source you recognise, and you have time to fix it. At
p=reject the same event is an outage for that sender, and the first
report of it is usually a customer asking why the invoices stopped.
Enforcement is the point at which monitoring has to become continuous
rather than a project with an end date.
Indirect mail flows fail on purpose
Two flows break under p=reject even when every sender you control is
perfectly aligned, and it is better to decide about them deliberately
than to discover them afterwards.
Forwarding. A message forwarded by the recipient’s own mailbox rule (or an alumni address, or a role account that redirects elsewhere) breaks SPF, because the forwarding host is not in your SPF record. DKIM survives if the forwarder did not touch the signed content. A sender aligned only by SPF therefore fails DMARC after forwarding; the same sender aligned by DKIM passes. This is the strongest practical argument for getting DKIM alignment on every sender before enforcing, not just SPF.
Mailing lists. Lists commonly add a subject tag or a footer, which
invalidates the original DKIM signature, and they resend from their own
server, which breaks SPF. Under p=reject, posts from your users to
lists that do not rewrite the From header are rejected by every
subscriber’s mailbox provider that honours your policy. Well-run lists
detect a reject policy and rewrite From to work around it; older ones
do not. DMARCbis is explicit that domains whose users post to mailing
lists should think hard before publishing p=reject, and that a
subdomain or separate domain for those users is the usual answer.
What a safe move to reject looks like
The stages are the ones in how to publish a DMARC record; the point here is what has to be true before each step.
- At
p=none, until the inventory is complete. Every source in the aggregate reports is identified — named, owned by a team, and either aligned or explicitly decided against. There are no rows you cannot explain. The window has covered at least one full billing and reporting cycle of your business, so the quarterly and annual senders have had a chance to appear. - At
p=quarantine; t=y, for at least a month. Quarantine is the rehearsal: a sender you missed lands in spam rather than disappearing, which means someone tells you about it.t=yis the DMARCbis testing flag that signals to receivers you are in a trial phase. Watch the reports for any recognised source whose alignment slips. (pctwas the older way to phase this in; DMARCbis removed it, and the wizard no longer offers it.) - At
p=reject, withoutt=y, only when quarantine has run clean. Lower the DNS TTL on the_dmarcrecord before the change so a rollback takes minutes, not a day. Keep watching the reports with the same attention as before: the enforcement stage is where a new unknown source is a problem to solve within hours, not a curiosity.
If a disposition=reject row appears for a source you recognise, the fix
is usually to drop back to p=quarantine, align that sender, and return
— not to stay at reject and hope the volume is small. Mail that was
refused while you decided is not recoverable.
Reading your own reports for the unknowns
The report data is where the unidentified senders are. If you are not
yet using a monitoring service, the
XML-to-human Converter turns a raw aggregate
report into a table of sources with their alignment results and
dispositions, in the browser, without uploading it. Sort by source and
look for the rows you cannot name; those are the senders that a move to
p=reject would cut off. DMARCLoop does the same thing continuously,
resolves each source to a named service where it can (see
how DMARCLoop identifies sources),
and tells you when the evidence says the next step is safe rather than
leaving that judgement to a calendar.