19 April 2026 · 12 min read
When your mail is forwarded, DKIM is where the failures show up
You set up DKIM, you watched your reports go green, and then a particular slice of traffic started failing authentication: messages that went through a forwarder. A staff member auto-forwards their work address to a personal Gmail account. A customer is on a university mailing list. A sales lead has a info@ alias that redirects everything to three people. In every one of these cases the message leaves your server perfectly signed and arrives at the final mailbox with a broken DKIM signature.
This is one of the most common and most misunderstood DMARC failure patterns. It is not a misconfiguration on your side, and it is rarely something you can fully prevent. But you can understand exactly what is happening, work out how much of your traffic it affects, and stop it from blocking your move to p=reject. This article walks through the mechanics of how forwarding breaks DKIM, what part of the signature survives and what does not, the role ARC plays, and the concrete steps that reduce the damage.
If you want to confirm your DKIM is signing correctly in the first place before you blame forwarding, run your domain through the DKIM checker. This article assumes your direct mail already authenticates and the problem only appears on relayed paths.
A quick recap of what DKIM actually signs
To understand why forwarding breaks DKIM you need to be precise about what DKIM covers. DKIM does not sign "the email" as a vague whole. A DKIM-Signature header lists exactly which fields are protected, and the receiver recomputes a cryptographic hash over those exact bytes.
A typical signature header looks like this:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=yourdomain.com; s=selector1; t=1718900000;
h=from:to:subject:date:message-id:mime-version:content-type;
bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=;
b=K7Hkn9q2... (the cryptographic signature)
Two parts matter here:
- The
bh=value is the body hash: a hash of the message body, after a defined canonicalisation. If the body changes by even a single byte that canonicalisation does not absorb, the body hash no longer matches and the signature fails. - The
h=list names the headers that are signed, andb=is the signature over those header values plus the body hash. If any signed header is altered, removed or reordered in a way the canonicalisation does not tolerate, the signature fails.
The c=relaxed/relaxed field is the canonicalisation: the first token applies to headers, the second to the body. "Relaxed" is forgiving about some whitespace and header-case changes. "Simple", the stricter alternative, fails on almost any change at all. Most senders use relaxed, which is exactly why a relaxed-signed message can survive small reformatting but still breaks under a real content change.
The crucial point: DKIM is decoupled from the connection. It does not care which IP relayed the message or what the envelope sender is. That is what makes it survive forwarding better than SPF does. But it is brittle in a different way: it depends on the bytes of the message staying intact.
Why forwarders break DKIM: the body-hash problem
When a forwarder simply relays a message untouched, DKIM survives. Plain .forward style redirection, or a server-side alias that does nothing but change the envelope recipient and re-emit the same MIME bytes, will usually keep both the body hash and the header signature valid. In that ideal case your DKIM passes at the destination and your DMARC alignment holds, because DKIM-based alignment compares the d= domain in the signature with the From header domain, and forwarding does not touch either.
The trouble is that very few forwarders are truly transparent. The common breakages are:
- Footers and banners. Mailing lists append "You are subscribed to..." footers. Corporate gateways add "This message originated outside the organisation" warning banners. Any added text changes the body, so the
bh=body hash no longer matches. Signature fails. - Subject tagging. Mailing lists prepend
[list-name]to the subject. Ifsubjectis in the signedh=list (it nearly always is), modifying it breaks the header signature. - Re-encoding the body. Some relays decode quoted-printable or base64 and re-encode it differently, convert line endings, rewrap long lines, or transcode character sets. Each of these rewrites body bytes.
- MIME restructuring. Anti-virus and content-filtering gateways frequently rebuild the MIME tree, strip attachments into a different structure, or add a
X-scanning header inside the signed set. - Link rewriting. "Safe links" protection products rewrite every URL in the body to route through a click-time scanner. That is a wholesale body change and is one of the most reliable DKIM destroyers in enterprise mail flows.
Notice the asymmetry. SPF breaks on forwarding because the relaying server is not in your SPF record, so the path-based check fails the moment the Return-Path is unchanged but the connecting IP changes. DKIM breaks on forwarding only when the content changes. So the two mechanisms fail on different paths, which is precisely why DMARC needs only one of them to pass and align.
What survives forwarding and what does not
It helps to hold a clear mental model of the three layers and which ones forwarding touches.
- The envelope (SMTP MAIL FROM / Return-Path). Forwarders almost always rewrite this, because bounces have to come back to the forwarder, not to you. This is what kills SPF on forwarded mail.
- The DKIM signature. Survives if and only if the signed headers and the body are not modified beyond what the canonicalisation tolerates. Survives plain redirection; dies on footers, subject tags, banners and re-encoding.
- The From header. Forwarders should not, and usually do not, rewrite the visible From address. This is the one stable anchor DMARC depends on. (Some mailing lists do rewrite From into the list's own domain. That is "From munging", and it is a deliberate workaround we cover below.)
So the failure spectrum looks like this:
- Clean redirect: SPF fails (new IP), DKIM passes (untouched body), DMARC passes on DKIM alignment. You are fine.
- List with footer and subject tag: SPF fails, DKIM fails (body and subject altered), DMARC fails. This is the painful case.
- List with From munging: SPF and DKIM are now evaluated against the list's domain, your DMARC is not in play at all, and your domain is no longer in the visible From. Different problem, covered later.
The reason this matters for your project is that the second case shows up in your aggregate reports as DMARC failures from IP addresses you do not recognise, with no SPF pass and no DKIM pass, even though the underlying mail is completely legitimate. If you react to that by tightening policy without understanding it, you risk junking real mail to forwarded recipients.
Reading forwarding failures in your DMARC reports
You diagnose this from your RUA aggregate data, not from a single message. Forwarding has a recognisable fingerprint:
- The source IP belongs to a mailbox provider or a known relay (Google, Microsoft, a university, a hosting company) rather than to your own sending infrastructure or your ESP.
- SPF result is
failorsoftfailbecause that IP is not authorised in your SPF, and theheader_fromaligns with your domain but the envelope domain does not. - DKIM result is
failwith ad=that is still your domain, which tells you the signature was yours but got mangled in transit, as opposed to being missing entirely. - Volume is low and spread across many small sources rather than concentrated, because each forwarding recipient is its own little stream.
Contrast that with a genuine spoofing source: usually no valid DKIM signature from your domain at all, often from bulletproof or compromised hosts, and frequently higher volume bursts. Telling the two apart is the entire job, and it is why you should not treat every fail line as an attack.
Load your reports into the DMARC report analyzer or the broader DMARC analyzer and group by source. The forwarding sources separate out quickly once you sort by provider and look at the DKIM d= column. If a source shows your own d= on a DKIM fail from a third-party mailbox host, that is forwarding, not abuse.
For the related case where everything looks like it should pass but DMARC still fails, see DMARC fails but SPF and DKIM pass, which deals with the alignment trap rather than the forwarding trap.
The role of ARC: who it helps and who it does not
Authenticated Received Chain (ARC) exists specifically because of the forwarding problem. The idea is simple and worth understanding clearly, because ARC is widely misunderstood as a thing you configure to fix your own forwarded mail. It mostly is not.
Here is the mechanism. When a forwarder receives your message, it evaluates authentication as it arrived (DKIM passed, SPF passed, DMARC passed). It then stamps that verdict into a set of ARC headers and signs them with its own key:
ARC-Seal: i=1; a=rsa-sha256; t=1718900100; cv=none;
d=forwarder.example; s=arc; b=...
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;
d=forwarder.example; s=arc; h=from:to:subject:date; bh=...; b=...
ARC-Authentication-Results: i=1; mx.forwarder.example;
dkim=pass header.d=yourdomain.com; spf=pass; dmarc=pass
Now when the message reaches the final receiver with a broken DKIM signature, that receiver can look at the ARC chain, verify the forwarder's ARC seal, and see "an intermediary I trust attests that this message authenticated correctly before they modified it". The receiver can then choose to honour that and not apply your DMARC policy as a reject.
The important truths about ARC:
- It is implemented by the forwarder and honoured by the final receiver. As the original sender, you do almost nothing. You cannot make a forwarder add ARC, and you cannot make a receiver trust it.
- It is advisory, not binding. A receiver is free to ignore an ARC chain, and many weight it by how much they trust the sealing intermediary. An unknown forwarder's ARC seal carries little authority. Google's and Microsoft's seals carry a lot.
- It does not put a green tick on the message. ARC's job is to give the receiver a reason not to reject mail that would otherwise fail DMARC. It rescues legitimate forwarded mail; it does not authenticate it the way DKIM does.
So ARC is genuinely the right structural answer to forwarding, and the large mailbox providers do seal and honour it, which is why forwarding through Gmail or Microsoft 365 increasingly survives a DMARC p=reject. But you should not plan around ARC saving every forwarded message, because the long tail of small forwarders and on-premise gateways often do not seal at all.
How to reduce the impact, in order of leverage
You will not eliminate forwarding breakage. You can shrink it and stop it from blocking enforcement. Here is what actually moves the needle, roughly from highest to lowest leverage.
1. Sign with relaxed canonicalisation and a minimal header set
Use c=relaxed/relaxed, which most platforms do by default. Relaxed body canonicalisation tolerates trailing whitespace and blank-line changes that simple canonicalisation rejects outright, so it survives more benign reformatting.
For the signed header list (h=), sign the headers that matter for integrity and identity (from, subject, date, message-id, to, content-type, mime-version) and avoid over-signing volatile headers a relay might touch. The single most useful detail here is oversigning: signing a header name one extra time than it appears (for example listing from twice in h=) prevents an attacker or a relay from adding a second copy of that header without breaking the signature. Sign from defensively; do not bloat the list with headers that intermediaries routinely rewrite.
2. Do not let the body change before you sign
If you control the sending pipeline, make DKIM signing the last step before the message leaves, so nothing downstream of the signer rewrites the body. A surprising number of self-inflicted "forwarding" failures are actually a local gateway re-encoding the body after signing. Confirm the message that left your border is byte-identical to what you signed. Our DKIM signature did not verify guide covers diagnosing that class of break in detail.
3. Keep SPF healthy so the non-modifying forwards still align another way
Forwarding breaks SPF by IP and DKIM by content, but those failures do not always coincide. A clean redirect keeps DKIM intact, and DMARC passes on DKIM alignment regardless of the broken SPF. So a correct, lint-clean SPF record does not rescue content-modifying forwards, but it keeps your overall pass rate high on the larger pool of plain redirects and direct mail. Check yours with the SPF checker and make sure you are under the ten-lookup limit, because an SPF PermError drops SPF to a non-pass for all mail, which removes one of your two alignment chances everywhere, forwarded or not. If you are wrestling with intermittent SPF resolution, see Fix SPF TempError.
4. Rely on the big forwarders' ARC, and verify it is being honoured
For the dominant forwarding paths (Gmail, Microsoft 365, major universities) ARC is doing real work. You can see the effect in your reports: as you move toward enforcement, forwarded mail through ARC-sealing providers continues to be delivered while genuine spoofing gets rejected. You do not configure this, but you should watch for it, because it tells you which forwarding sources are safe to ignore in your enforcement decision.
5. For mailing lists, accept From munging or move the list to a subdomain
Mailing lists are the hardest case because they both modify the body (footer) and tag the subject. The list software's standard mitigation is From munging: rewriting the visible From from you@yourdomain.com to something like you via List <list@listdomain.org>, with a Reply-To back to you. Once munged, the message authenticates as the list's domain, your DMARC no longer applies to it, and it is delivered. The cost is that your name and brand are partly obscured in the From line and replies route through the list. Many list operators enable munging automatically when they detect a sender domain at p=quarantine or p=reject, which is exactly why publishing a strict policy can trigger the correct list behaviour rather than break it.
If you run the list yourself, the cleaner option is to send list mail from a dedicated subdomain (for example lists.yourdomain.com) with its own DKIM selector and its own DMARC policy, keeping the strict policy on your primary domain.
6. Do not stay at p=none out of forwarding fear
The instinct is to keep your policy at p=none forever because forwarded mail fails. That is the wrong lesson. Forwarding failures at p=none are reported but not enforced, so they cost you nothing except noise. The path forward is to quantify the forwarding slice (it is usually a small single-digit percentage of total volume), confirm the bulk of it flows through ARC-sealing providers, and then move to p=quarantine with a pct ramp before going to p=reject. You can model the policy with the DMARC generator and watch the enforcement impact in continuous monitoring before committing.
A worked decision example
Suppose your monthly aggregate data shows 50,000 messages. 47,000 authenticate cleanly on direct paths. 3,000 are failing DMARC, and when you group the failures:
- 2,100 are from
google.comandoutlook.commailbox IPs, DKIMd=yourdomain.combutfail, SPFfail. These are forwards through ARC-sealing providers. They are being delivered today and will keep being delivered under enforcement. - 600 are from a single university relay, DKIM
failwith yourd=, no ARC visible. Legitimate list traffic. Candidate for a subdomain or for accepting munging. - 300 are from scattered hosts with no DKIM signature from your domain at all and SPF
fail. That is spoofing, and it is exactly what you wantp=rejectto stop.
The right move is not to stall. It is to move to p=quarantine, watch that the 2,100 ARC-rescued messages keep landing, address the 600 list messages structurally, and let the 300 spoofs get filtered. The forwarding noise was never a reason to leave your domain spoofable.
The practical takeaway
DKIM failing after forwarding is normal, it is not your misconfiguration, and it is rarely fully fixable, because the failure happens in infrastructure you do not control. What you can do is decisive:
- Understand that forwarding breaks DKIM through body and header modification, not through the connection, which is the opposite of how it breaks SPF.
- Sign with relaxed canonicalisation, a tight oversigned header set, and signing as the final pipeline step.
- Read your aggregate reports to separate forwarding failures (your
d=, mailbox-provider IPs) from real spoofing (no signature, hostile hosts). - Lean on ARC where the big providers supply it, and use From munging or a list subdomain for mailing lists.
- Do not let forwarding keep you parked at
p=none. Quantify it, confirm ARC coverage, and ramp to enforcement.
Start by confirming your signing is correct with the DKIM checker and your overall posture with the DMARC checker, then watch how forwarded streams behave as you tighten policy. If you would rather not interpret aggregate reports and stage the policy ramp by hand, our done-for-you DMARC service classifies forwarding versus abuse in your reports and takes the domain from p=none to p=reject without dropping legitimate forwarded mail along the way.