p=none to p=reject. Direct mail to the big providers still lands fine, but some senders now get bounces for messages to a few specific recipients. When you look closer, those recipients don't actually read mail at the address you sent to. Their mailbox forwards everything to a different provider, and the rejection happens on that second hop.
The bounce makes it look like your authentication is broken. Usually it isn't, at least not in the way people first assume. The headers on the forwarded copy tell you exactly which check failed and why, and once you can read them the fix is usually narrow.
What the bounce is really telling you
Find the Authentication-Results header on the forwarded copy
Authentication-Results. The receiving server adds it after running SPF, DKIM, and DMARC checks, and it records the result of each one.
The catch is that a rejected message never reaches the final mailbox, so you can't read its headers there. Two practical ways around that:
- Temporarily send a test message to the forwarding address while the DMARC policy is relaxed, or forward to a mailbox you control on another provider. Then open the copy at the final destination and view the raw source. Most webmail clients have an option along the lines of show original or view source.
- Check whether the bounce includes the original message or its headers as an attachment. Many do, though those are usually the headers as they left your server, not the final receiver's verdict.
Authentication-Results line added by the final provider (it's typically near the top, because headers are prepended as mail moves). On a forwarded message that would fail under p=reject, it tends to look something like this:
TEXT
Illustrative output format (layout varies by receiver):
Authentication-Results: mx.final-provider.example;
spf=fail (domain of example.com does not designate 203.0.113.25 as permitted sender) smtp.mailfrom=example.com;
dkim=none;
dmarc=fail (p=REJECT) header.from=example.comsmtp.mailfrom is the envelope sender, the Return-Path domain that SPF checks. The IP in the SPF result is the forwarder's server, not yours. dkim=none means no DKIM signature was found at all, and header.from is the visible From domain that DMARC cares about. If you want a deeper walkthrough of every field and what alignment means for each one, see Reading Authentication-Results Headers to Fix DMARC Alignment.
Why SPF fails after forwarding, and why that's expected
pass, but for the forwarder's domain. DMARC requires the SPF-authenticated domain to align with the From domain, so a pass for someone else's domain still doesn't help you. Either way, SPF alignment is gone after the first hop.
That leaves DKIM. DMARC passes if either SPF or DKIM passes and aligns with the From domain. DKIM is a cryptographic signature over the message headers and body, and it doesn't care which IP delivers the message. As long as the forwarder doesn't modify the signed parts, the signature verifies at the final receiver just as it did at the first one.
That's why forwarded mail kept arriving under p=none: nothing was being enforced. Under p=reject, any message that relied only on SPF has no aligned pass left once it's forwarded.
Red herrings worth ruling out
p=reject itself isn't the bug. It exposed a gap that was already there. Rolling back to p=none stops the bounces, but it also stops the protection you set out to get.
Confirm DKIM is signing with your own domain
dkim=none: your mail isn't being DKIM-signed at all.dkim=passwith aheader.d=value that isn't your domain: the message is signed, but with a hosting hostname or a third-party service's domain, so it doesn't align.dkim=fail: a signature exists but broke in transit, often because something in the path modified the body or signed headers.
BASH
# Replace 'default' with your selector (the s= value in the DKIM-Signature header)
# and example.com with your domain
dig +short TXT default._domainkey.example.comv=DKIM1 and a p= public key. An empty result means the record is missing or published under the wrong name.
For dkim=fail on forwarded copies only, the forwarder or a mailing list is probably changing the message. That's outside your control, though some receivers consider ARC (Authenticated Received Chain) headers added by trusted forwarders. Whether they do is up to each receiver, so treat it as a bonus rather than a fix.
The same pattern applies to every service that sends as your domain. If one tool relies only on SPF, its mail will fail DMARC the moment it's forwarded. What to Audit Before Switching DMARC Policy from None to Reject covers how to catch those senders.
Verifying the fix
dkim=pass with header.d= set to your domain, and dmarc=pass. SPF will most likely still say fail or pass for a different domain. That's fine, and expected.
Your DMARC aggregate reports are a good second check. Forwarded mail shows up as rows from IPs you don't recognize with SPF failing. If DKIM passes and aligns on those rows, DMARC passes and the mail is delivered. If DKIM is missing on them, those are the messages that bounce under p=reject.
If you're on a support desk and a customer reports bounces right after a DMARC change, ask for a forwarded test copy's raw headers before touching DNS. In most cases the answer is already there: SPF failed because of the extra hop, and DKIM either wasn't present or wasn't signed with the customer's own domain. Make sure every sender signs DKIM with the From domain, and forwarding stops being a problem for DMARC.