ARC (Authenticated Received Chain): Why Forwarded Emails Keep Failing Authentication

hangrydev ·

Forwarded Emails Break DMARC. That’s by Design.

You set up SPF, DKIM, and DMARC. Everything passes. Then someone on a mailing list complains they never got your message. Or a user with a .forward rule on their university email says your password reset went to spam.

You check the headers. DMARC failed.

Your setup is fine. The forwarding broke it. So why did DMARC fail if everything was configured correctly? Because DMARC was designed to fail in this scenario. The authentication chain can’t survive a relay that changes the sending IP or modifies the message body.

ARC (Authenticated Received Chain, defined in RFC 8617) exists to solve this. It lets intermediaries preserve authentication results so the final receiver can make an informed decision instead of blindly rejecting a forwarded message that was perfectly authenticated at origin.

Why Forwarding Destroys Authentication

To understand ARC, you need to understand exactly what breaks when an email gets forwarded.

SPF dies on every forward

SPF validates the IP address of the server talking to the receiver. Your domain’s SPF record says “these IPs are allowed to send as me.” When a mailing list or a .forward rule relays your message, the receiving server sees the forwarding server’s IP. That IP isn’t in your SPF record.

SPF fails. Every time. No exceptions.

Some forwarders use SRS (Sender Rewriting Scheme) to rewrite the envelope sender, which lets SPF pass for the rewritten domain. But that domain doesn’t match your From: header, so SPF alignment still fails under DMARC.

DKIM survives… sometimes

DKIM signs the message body and specific headers with a cryptographic hash. The signature travels with the message, so it can survive forwarding. In theory.

In practice, mailing lists add footers. Corporate gateways append disclaimers. Content filters rewrite URLs. Any of these modifications invalidate the DKIM signature because the body hash no longer matches.

Industry analyses have consistently found that a significant share of legitimate forwarded messages end up with broken DKIM signatures due to content modification by intermediaries. Mailing list footers, corporate disclaimers, and URL rewrites are the most common causes.

DMARC sees one failure and rejects

DMARC requires either SPF or DKIM to pass and align with the From: domain. For forwarded email, SPF alignment is gone. If DKIM also broke, DMARC fails entirely. And if you’ve followed best practices and set your DMARC policy to p=reject, the message gets dropped.

Not spam-foldered. Dropped. The recipient never sees it.

RFC 7960 (Interoperability Issues between DMARC and Indirect Email Flows) documented this problem back in 2016. It took until 2019 for ARC to get published as RFC 8617, and several more years for widespread adoption among major providers.

What ARC Actually Does

ARC doesn’t fix SPF or DKIM. It doesn’t change how forwarding works. Instead, it creates a chain of custody.

Each intermediary that handles the message records the authentication results it observed when the message arrived, signs those results, and seals the chain. The final receiving server can then look at the ARC chain and say: “DMARC failed, but a trusted intermediary authenticated this message successfully before forwarding it.”

Think of it like a package tracking system. The package (your email) passes through multiple warehouses (mail servers). Each warehouse stamps a record of the package’s condition when it arrived. If the package arrives damaged at the final destination, the receiver can check the stamps to see where it was last intact.

The Three ARC Headers

Every intermediary in the chain adds exactly three headers, each tagged with an instance number (i=1 for the first hop, i=2 for the second, and so on).

ARC-Authentication-Results (AAR)

This is a snapshot of the authentication check results at the time the intermediary received the message. It follows the same format as the standard Authentication-Results header (RFC 8601).

ARC-Authentication-Results: i=1; mx.list.example.org;
    dkim=pass header.d=sender.com;
    spf=pass smtp.mailfrom=sender.com;
    dmarc=pass header.from=sender.com

The intermediary ran SPF, DKIM, and DMARC checks before forwarding. All passed at that point. This record survives even after the forward breaks SPF on the next hop.

ARC-Message-Signature (AMS)

This is a DKIM-like signature over the message headers and body, created by the intermediary. It proves the message content hasn’t been tampered with since the intermediary handled it.

ARC-Message-Signature: i=1; a=rsa-sha256; d=list.example.org;
    s=arc-selector; c=relaxed/relaxed;
    h=from:to:subject:date:message-id;
    bh=abc123...;
    b=xyz789...

If a later hop modifies the message, this signature breaks. But that’s fine. The ARC-Seal (next header) still validates, and the receiver can see that the modification happened after the intermediary’s attestation.

ARC-Seal (AS)

The seal is a signature over all previous ARC header sets plus the current one. It chains everything together and prevents anyone from stripping or reordering the ARC headers after the fact.

ARC-Seal: i=1; a=rsa-sha256; d=list.example.org;
    s=arc-selector; cv=none;
    b=def456...

The cv= (chain validation) field indicates the status of the chain: none for the first hop, pass if the previous ARC sets validated, fail if they didn’t. A receiver seeing cv=fail anywhere in the chain knows something went wrong.

How the Chain Builds Across Hops

Here’s a real-world scenario. You send an email from [email protected] to a mailing list at [email protected]. The list forwards it to [email protected].

Hop 0: Your mail server to the mailing list. The list server receives your message. It checks SPF (pass), DKIM (pass), DMARC (pass). It adds an ARC set with i=1, recording all three passes.

Hop 1: Mailing list to Gmail. The list server adds a footer to the message body (“You’re receiving this because you subscribed to dev-list”). It forwards the message from its own IP.

Gmail receives the message and checks authentication. SPF fails (the list server’s IP isn’t in company.com’s SPF record). DKIM fails (the footer broke the body hash). DMARC fails (neither SPF nor DKIM aligned).

But Gmail also checks the ARC chain. The i=1 ARC set from lists.example.org shows that DMARC passed before the forward. Gmail trusts lists.example.org as an ARC signer. So instead of rejecting the message, Gmail delivers it.

That trust relationship is the key piece. ARC headers from an unknown or untrusted intermediary don’t help.

Who Supports ARC

The major mailbox providers all validate ARC chains on inbound mail.

Gmail has validated ARC headers since at least 2017, before the RFC was even finalized. They were one of the primary contributors to the specification. Google’s documentation states that ARC results factor into their DMARC override decisions for messages from trusted forwarders.

Microsoft added ARC validation for Exchange Online and Outlook.com. Their anti-spoofing documentation explicitly references ARC as a mechanism for handling indirect mail flows. Given Microsoft’s 2025 bulk sender requirements, proper authentication is now a baseline expectation, and ARC helps forwarded mail meet that bar.

Yahoo validates ARC chains as part of their DMARC processing pipeline. Since Gmail and Yahoo both reject non-compliant email at the SMTP level, ARC has become a practical necessity for any forwarding infrastructure that handles mail destined for these providers.

Major mailing list software also generates ARC headers. Mailman 3 added ARC signing support. Google Groups has been signing since ARC’s early days. Enterprise mail gateways from Proofpoint, Mimecast, and Barracuda added ARC support between 2020 and 2023.

ARC Doesn’t Fix Everything

ARC has real limitations that are worth understanding if you’re building email infrastructure.

Trust is a closed loop. ARC only works if the receiving server trusts the intermediary’s ARC signature. Gmail trusts Google Groups. Microsoft trusts its own relays. But there’s no universal “ARC trust list.” If you run a small mailing list and sign with ARC, Gmail has no reason to trust your signatures. There’s no public registry of trusted ARC signers. Each receiving provider maintains its own list, and getting on it typically requires an established reputation. M3AAWG (Messaging, Malware and Mobile Anti-Abuse Working Group) has promoted ARC adoption, but the trust decisions remain provider-specific.

It doesn’t prevent abuse. A malicious intermediary could forge ARC headers claiming everything passed. That’s why trust matters. Receivers only honor ARC from signers they’ve vetted.

Chain validation can fail. If any intermediary in the chain produces an invalid ARC set, the whole chain is broken. cv=fail propagates forward. One misconfigured relay poisons the entire path.

No DMARC policy override guarantee. Even with valid ARC from a trusted signer, the receiving server isn’t required to override a DMARC reject policy. ARC provides evidence. The receiver decides what to do with it. RFC 8617 is explicit that ARC is a mechanism for expressing and validating authentication results across hops. It doesn’t mandate any particular disposition. What the receiver does with that information is entirely local policy.

What This Means for Developers

Most developers don’t run mail servers. You’re not going to implement ARC signing yourself. So why should you care? Because understanding ARC matters for a few reasons.

Debugging forwarding failures. When a user reports they’re not receiving your emails, and they have a forwarding rule, ARC (or the lack of it) explains why. Check the raw headers. If there’s no ARC chain, the intermediary isn’t preserving authentication. If the ARC chain shows cv=fail, something broke in transit.

Choosing email infrastructure. If your application sends email through a relay or mailing list, check whether that service signs with ARC. Services that don’t sign are more likely to cause delivery failures for users who forward.

Validating recipient addresses. Forwarding-related bounces look like permanent failures from the outside. An email validation API can tell you whether the original address is deliverable before you send, helping you separate “the address is dead” from “the forwarding chain broke authentication.”

Understanding DMARC report noise. Your DMARC aggregate reports will show failures from forwarded messages. These aren’t spoofing attempts. They’re legitimate forwarding breaking authentication. Knowing about ARC helps you read those reports without panicking about failures that aren’t attacks.

Inspecting ARC Headers Yourself

Want to see ARC in action? Send an email to a mailing list you’re subscribed to (one that forwards to a Gmail or Outlook address). Open the received message and view the full headers.

# In Gmail: open message > three dots > "Show original"
# Look for headers starting with ARC-

# You can also use command-line tools to check DKIM/ARC signatures
# on a saved .eml file:
pip install authheaders
python3 -c "
import authheaders
# Parse and display ARC chain from raw headers
"

Look for the three ARC headers with matching instance numbers. Check the cv= value in the ARC-Seal. If it says pass, the chain is intact. If the AAR shows dmarc=pass at the first hop but the top-level Authentication-Results shows dmarc=fail, you’re looking at a classic forwarding scenario where ARC preserved the original results.

The Bigger Picture

Email authentication is a stack. SPF, DKIM, and DMARC handle direct delivery. ARC handles the gaps created by forwarding. Together, they give receiving servers enough information to make good decisions about whether a message is legitimate.

The trend is clear. Providers are getting stricter, not looser. Gmail, Yahoo, and Microsoft all enforce DMARC now. They all support ARC. The infrastructure exists for forwarded email to survive authentication checks, but only if the intermediaries are doing their part.

If you’re building systems that send email, get your SPF, DKIM, and DMARC right first. ARC is someone else’s job (the forwarder’s). But when you’re debugging why a user’s forwarded copy of your password reset went to spam, knowing that ARC exists and how it works saves you hours of chasing the wrong problem.