toolhq.io

All posts
7 min readby Jameel Haider

ARC: why forwarded mail fails SPF and DKIM

A message leaves your server with SPF and DKIM both passing. It arrives at a recipient who forwards it, or it goes through a mailing list, and the final destination reports a DMARC failure. Nothing changed at your end. The failure is a structural property of how forwarding interacts with the two authentication mechanisms, and ARC is the protocol built to work around it.

Why SPF cannot survive forwarding

SPF authorises an IP address to send mail for a domain, checked against the envelope sender, not the visible From header.

When a mailbox forwards a message, the forwarding server connects to the final destination from its own IP. That IP is not in your SPF record, and it should not be. The destination checks SPF, sees an unauthorised address, and records a failure.

This is not a bug in SPF. SPF asks "did this message come from a server the domain permits", and the honest answer after forwarding is no. The message did come from somewhere else.

Sender Rewriting Scheme (SRS) is the traditional mitigation. The forwarder rewrites the envelope sender to a domain it controls, so SPF is evaluated against the forwarder and passes. It keeps SPF working but breaks DMARC alignment, because the envelope domain is now the forwarder's rather than yours. It shifts the problem rather than removing it.

Why DKIM usually survives, until it does not

DKIM signs headers and body with a key published in your DNS. Forwarding does not change the signature, so a plain forward normally leaves DKIM intact. This is why DMARC passes on most forwarded mail: it needs only one of the two to pass and align, and DKIM is the one that travels.

Mailing lists break it. A list typically does some combination of:

  • Adding a subject tag such as [list-name]
  • Appending a footer with unsubscribe instructions
  • Rewriting or adding headers
  • Re-encoding the body

Any of these invalidates the signature, because the signed content no longer matches. Now SPF fails because of the path and DKIM fails because of the modification, so DMARC fails outright. A domain at p=reject has its list mail rejected, which is why list operators spent years rewriting the From header to their own domain, and why that workaround is unpleasant for everyone.

What ARC adds

ARC (RFC 8617) does not repair the broken authentication. It preserves a record of what an intermediary observed before it made its changes, so a later receiver can take that testimony into account.

Each intermediary that participates adds three headers, numbered by position in the chain:

  • ARC-Authentication-Results records the SPF, DKIM and DMARC results the intermediary saw on arrival. This is the evidence: it says the message authenticated correctly when it reached me.
  • ARC-Message-Signature signs the message as it existed at that point, in the same manner as DKIM.
  • ARC-Seal signs the ARC headers themselves, including previous sets, binding the chain together so an entry cannot be removed or reordered without detection.

The final receiver validates the chain. If it holds, and the receiver trusts the intermediaries in it, it may accept the message despite the failed SPF and DKIM, on the basis that a party it trusts saw the message authenticate before modifying it.

That conditional is the important part. ARC does not oblige anyone to accept anything. It supplies evidence, and the receiver decides what the evidence is worth based on the reputation of the sealing domain. A chain sealed by an unknown forwarder carries little weight.

Who deploys it

This is the point that causes confusion. ARC is deployed by intermediaries, not by originating domains.

If you send mail from your own domain, there is nothing to configure. You cannot add ARC headers to your own outbound mail in a way that helps, because ARC is a statement about what someone else observed. Adding a seal to a message you originated proves nothing that DKIM does not already prove.

ARC matters to you if you operate something in the middle:

  • A mailing list
  • A forwarding service
  • A security gateway that rewrites messages
  • A shared inbox or ticketing system that relays mail onward

If you run any of those and do not seal, mail passing through you fails downstream and gets blamed on the original sender.

Large providers including Gmail and Microsoft both seal and evaluate chains, which is why forwarding between major providers usually works despite the failures underneath.

Reading an ARC chain

Open the raw source of a message that has passed through a list or forwarder and look for headers with an i= index:

ARC-Seal: i=1; a=rsa-sha256; t=1755000000; cv=none;
        d=lists.example.org; s=arc; b=...
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;
        d=lists.example.org; s=arc; h=from:to:subject:date; bh=...; b=...
ARC-Authentication-Results: i=1; lists.example.org;
        spf=pass smtp.mailfrom=example.com;
        dkim=pass header.d=example.com;
        dmarc=pass header.from=example.com

The cv tag on the seal is the chain validation state: none for the first entry, pass if the chain up to that point validated, fail if it did not. A cv=fail anywhere means the chain is broken from there on and carries no weight.

Paste the full headers into the email header analyzer to see the ARC sets alongside the Received path and the standard authentication results, which makes it much easier to see where in the journey the failure was introduced.

What to do as a sender

You cannot deploy ARC to fix your own forwarded mail, but three things reduce the damage:

  1. Make sure DKIM is correct and aligned. DKIM is what survives plain forwarding. If DKIM is misconfigured or signs with the wrong domain, you lose the one mechanism that would have carried through. The email health check confirms the record resolves.
  2. Use relaxed alignment in DMARC. Strict alignment requires an exact domain match and fails on subdomains that would otherwise have passed. Relaxed is the default and the right choice for almost everyone.
  3. Read your aggregate reports before tightening policy. Forwarded and list mail shows up in DMARC reports as failures from sources you do not recognise. Distinguishing legitimate forwarding from actual spoofing is the whole job, and understanding DMARC aggregate reports covers how to tell them apart.

Moving to p=reject without accounting for forwarding is how organisations discover their own mail is being rejected. The reports exist precisely to prevent that.