DMARC Engine
Home/Blog/RFC 8617: the ARC standard explained
Blog

RFC 8617: the ARC standard explained

Forwarding breaks SPF alignment and DKIM signatures, so DMARC fails on mail you legitimately sent. ARC, defined in RFC 8617, lets a trusted intermediary vouch for the authentication verdict it saw before it touched the message. This is a hop-by-hop walk through the three ARC header fields, how sealing works, how chain validation runs, and what a final receiver actually does with an ARC result after forwarding.

22 March 2026 · 14 min read

RFC 8617: the ARC standard explained

A message leaves your domain, passes SPF and DKIM cleanly, and would sail through DMARC at p=reject. Then it hits a mailing list, or an account that auto-forwards to a different mailbox, or a security gateway that rewrites the body to add a banner. The forwarder changes the envelope sender or touches a signed header, and by the time the message reaches its final destination the SPF check is for the forwarder's IP, the DKIM signature no longer verifies, and DMARC fails. The receiver, following your p=reject policy to the letter, rejects a message you legitimately sent.

This is the forwarding problem, and it is the single biggest reason organisations hesitate to move to enforcement. ARC, the Authenticated Received Chain, defined in RFC 8617 (published July 2019 as Experimental), is the standard built specifically to address it. ARC does not replace SPF, DKIM or DMARC, and it does not change a single thing about how you publish your records. It is a mechanism that lets an honest intermediary vouch for what the authentication results looked like before it touched the message, in a way the next hop can cryptographically verify and choose to trust.

This article walks through RFC 8617 in detail: the three header fields ARC defines, how an intermediary seals a message, how the chain validation works hop by hop, and crucially what a final receiver does (and does not) do with an ARC result after forwarding. It is written for people who already understand DMARC alignment and want to know exactly what ARC adds. If you need the alignment concept first, DMARC alignment explained covers it; here we assume it.

Why DMARC breaks on forwarding in the first place

To see what ARC fixes, you have to be precise about what each authentication method binds to.

  • SPF authorises an IP address to send for the Return-Path (envelope MAIL FROM) domain. A forwarder typically resends from its own IP and often rewrites the envelope sender, so SPF either fails for your domain or passes for the forwarder's domain. Either way it does not align with your From:.
  • DKIM signs a chosen set of headers plus the body and binds them to a d= domain. As long as the signed content is untouched, a DKIM signature survives forwarding: the signature does not care which IP relays the message. But the moment an intermediary modifies a signed header, adds a footer to the body, or rewraps MIME parts, the hash no longer matches and the signature breaks.
  • DMARC passes if SPF or DKIM passes and aligns with the From: domain. After a typical forwarding hop, SPF has stopped aligning and DKIM has broken, so neither leg holds and DMARC fails.

The result is a structurally honest message that fails authentication through no fault of the original sender. Classic triggers:

  • Mailing lists (Mailman, Google Groups, listservs) that prepend [list-name] to the Subject, add an unsubscribe footer to the body, and resend from the list's own infrastructure. Subject and body are usually both DKIM-signed, so the signature breaks.
  • Account-level forwarding ("send a copy of everything to my other address"), where the forwarding server adds Received headers and sometimes resigns or rewrites parts.
  • Security gateways that insert a [EXTERNAL] banner or a "scanned safe" footer into the body.

For a deeper look at the forwarding failure mode on its own, see DMARC and forwarding and DKIM alignment and forwarding. The point for ARC is this: at the moment your message arrived at the intermediary, it very likely passed DMARC. ARC is a way for that intermediary to record that fact and pass it forward.

The core idea: preserving the original authentication verdict

ARC's premise is simple to state. Each intermediary that handles a message can, before it forwards it on, capture the authentication results it observed and attach them to the message in a tamper-evident way. The next intermediary does the same, building an ordered chain. The final receiver can then look back along the chain and reason: "DMARC fails for me right now, but a chain of intermediaries I trust attests that the message passed DMARC when it first entered the path, and the chain has not been broken since."

ARC does not assert that the original message was good. It asserts something narrower and more honest: here is what authentication looked like at each hop, and here is cryptographic proof that these statements were made by the parties claiming to make them and have not been altered since. Whether to act on that attestation is entirely the receiver's decision, and it hinges on whether the receiver trusts the intermediaries that signed the chain. ARC provides verifiable provenance, not trust. Trust is a local policy choice layered on top.

Two consequences fall out of this immediately:

  1. ARC is only useful between parties where the receiver has some basis to trust the sealer. A chain sealed by a reputable, well-behaved forwarder is worth acting on; a chain sealed by an unknown host is just data.
  2. ARC is built on the same cryptographic machinery as DKIM (the DomainKeys Identified Mail signing model), which is why the records, the key publication, and the canonicalisation all feel familiar if you know DKIM.

The three ARC header fields

RFC 8617 defines exactly three new header fields. Every intermediary that participates adds one of each, all tagged with the same instance number (i=), which is what orders the chain. The instance number starts at 1 for the first intermediary and increments by one at each subsequent hop, up to a maximum of 50.

ARC-Authentication-Results (AAR)

The ARC-Authentication-Results header is, in content, almost identical to the ordinary Authentication-Results header defined by RFC 8601, with one addition: it carries an i= instance tag. It records the SPF, DKIM and DMARC results that this intermediary observed when the message arrived at it.

ARC-Authentication-Results: i=1; mx.listserver.example;
    spf=pass smtp.mailfrom=you@yourdomain.com;
    dkim=pass header.d=yourdomain.com;
    dmarc=pass header.from=yourdomain.com

This is the substantive payload of an ARC hop. It is the intermediary saying, on the record, "when this message reached me, it passed SPF for your domain, carried a valid DKIM signature for d=yourdomain.com, and passed DMARC aligned to your From." The AAR is a frozen snapshot of the verdict at that hop, taken before the intermediary made any modifications that might break it downstream.

ARC-Message-Signature (AMS)

The ARC-Message-Signature is a DKIM-style signature over the message, taken by the intermediary at the moment it handles the message. Syntactically it looks like a DKIM-Signature header with an added i= instance tag.

ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;
    d=listserver.example; s=arc2024; t=1718900000;
    bh=2jUSOH9NhtVG...base64...;
    h=from:to:subject:date:message-id:mime-version:content-type;
    b=Xq9kP...base64signature...

The critical difference from a normal DKIM signature: the AMS signs the message as it leaves this intermediary, including the modifications the intermediary made. So a mailing list that rewrote the Subject and appended a footer signs the modified version with its AMS. This is exactly what makes ARC work across a body-mangling list. The list cannot save the original sender's DKIM signature (it broke it), but it can attest with its own fresh signature that the message it is forwarding is the one whose authentication it described in the AAR.

The AMS covers the message body and headers, but by convention and per the spec it does not include the ARC-Seal headers in its scope. It signs the message content, not the seal layer.

ARC-Seal (AS)

The ARC-Seal is what binds the whole chain together and makes it tamper-evident across multiple hops. It is also a DKIM-style signature, but its scope is different and very deliberate. The AS at instance i=N signs:

  • all the ARC-Authentication-Results, ARC-Message-Signature and ARC-Seal headers from instances 1 through N-1, and
  • the ARC-Authentication-Results and ARC-Message-Signature of its own instance N,

but it does not sign the message body at all. The seal's job is to protect the chain, not the content.

ARC-Seal: i=1; a=rsa-sha256; t=1718900000; cv=none;
    d=listserver.example; s=arc2024;
    b=hHdL2...base64sealsignature...

Note the cv= tag, the chain validation status. This appears only on the ARC-Seal. It records what the sealer concluded about the chain as received:

  • cv=none means there were no prior ARC headers; this is the first hop sealing a fresh chain.
  • cv=pass means the existing chain validated successfully before this intermediary added its own seal.
  • cv=fail means the existing chain was present but did not validate.

The very first seal in a chain must carry cv=none. Every subsequent seal carries cv=pass or cv=fail reflecting what the sealer found. Once any hop sets cv=fail, the chain is permanently failed: a broken chain cannot be repaired by a later, honest intermediary. This one-way property is central to ARC's integrity model and we return to it below.

Sealing: what an intermediary actually does

Putting the three headers together, here is the precise sequence an ARC-aware intermediary performs when it receives and forwards a message. Suppose it is the first intermediary, so it will write instance i=1.

  1. Evaluate authentication on arrival. Run SPF, DKIM and DMARC against the message exactly as received. Record the outcome.
  2. Validate any existing chain. Look for prior ARC sets. If none exist, the chain validation status is none. If they exist, validate them (described in the next section) and compute cv=pass or cv=fail.
  3. Write the ARC-Authentication-Results header for i=1, recording the SPF/DKIM/DMARC results from step 1.
  4. Apply its own modifications to the message (rewrite Subject, append footer, add banner, whatever this intermediary does).
  5. Compute and add the ARC-Message-Signature for i=1 over the now-modified message.
  6. Compute and add the ARC-Seal for i=1, signing the AAR and AMS of this instance plus all prior ARC headers (none, in the first-hop case), and stamping the cv= value from step 2.
  7. Forward the message.

The ordering matters. The AAR is recorded against the message as received (step 1), but the AMS signs the message as modified (steps 4 to 5). That gap, the verdict captured before modification but the signature taken after, is the whole trick. It lets the receiver reconstruct: "this intermediary saw a passing message, then changed it like so, and here is its signature over the changed version."

Each header is published and verified using DKIM-style DNS key records. The selector and domain in the AMS and AS (s=arc2024; d=listserver.example above) point at a TXT record holding the public key, exactly as DKIM does:

arc2024._domainkey.listserver.example. IN TXT
    "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GN...base64pubkey..."

If you understand how DKIM keys are published and selected, you already understand ARC key publication; the mechanics are the same. For a refresher on selectors see DKIM selectors explained, and you can inspect any DKIM-style key with the DKIM checker.

Chain validation: how the next hop checks the work

When an intermediary or a final receiver wants to validate an inbound ARC chain, RFC 8617 lays out a specific algorithm. The chain is the set of ARC sets numbered 1..N, where each set is one AAR, one AMS and one AS sharing an instance number. Validation proceeds roughly as follows:

  1. Find the highest instance number, N. That set's ARC-Seal is the most recent. Confirm the instances are a contiguous run 1, 2, ..., N with no gaps and no duplicates. Any structural anomaly (a missing instance, a duplicate, more than one of a header at the same instance) fails the chain.
  2. Check the seal chaining rule on cv. The seal at i=1 must be cv=none. Every seal at i>1 must be cv=pass (a cv=fail anywhere means a prior hop already declared the chain dead, and it stays dead).
  3. Verify the most recent ARC-Message-Signature (i=N). This confirms the message body and headers, as they currently stand, match what the most recent intermediary signed. If the AMS at i=N fails, the chain fails.
  4. Verify every ARC-Seal, from i=1 to i=N. Each seal signs all the ARC headers up to and including its own instance, so verifying them in order proves no ARC header in the chain has been altered or reordered since it was sealed.

If all of that holds, the chain is cv=pass: structurally sound, every seal intact, and the latest message signature valid. If any step fails, the chain is cv=fail.

A subtle but important point: only the most recent AMS is verified for content. The earlier AMS headers are not re-verified against the body (they could not be; later intermediaries changed the body). They are still protected by the seals, so their text cannot be tampered with, but the body assertion that matters for "is this the message that was forwarded" is the latest one. The earlier AARs remain meaningful because the seals guarantee they have not been edited, and because a downstream party that trusts those intermediaries can read the verdict each one recorded.

This is why a single broken hop poisons everything after it. If intermediary 2 produces an invalid seal, then when intermediary 3 validates the chain it computes cv=fail, stamps cv=fail into its own seal, and the failure propagates. There is no mechanism to "skip" a bad hop and trust the rest. The chain is only as trustworthy as its weakest seal.

What a final receiver does with ARC after forwarding

Here is the part that is most often misunderstood, so let us be exact about it. ARC does not override DMARC. A receiver that honours your p=reject policy still runs DMARC normally and still gets a DMARC failure on a forwarded message. ARC enters only as a local policy override input: a reason the receiver might choose, of its own accord, not to apply the failing DMARC disposition.

The decision flow at a DMARC-aware final receiver looks like this:

  1. Run SPF, DKIM and DMARC as usual. Suppose DMARC fails because of forwarding.
  2. Before applying the published policy (quarantine or reject), validate the inbound ARC chain.
  3. If the chain is cv=pass, look at the authentication results recorded in the earliest AAR (the verdict at the message's entry into the path). If that AAR shows the message passed DMARC when it first arrived, and the receiver trusts the sealers in the chain, the receiver may choose to deliver the message anyway, overriding the local reject.
  4. If the chain is cv=fail, or the receiver does not trust the sealers, or the original AAR did not show a DMARC pass, ARC provides no basis for an override and the published DMARC policy applies unchanged.

Three things deserve emphasis here.

It is permissive, never punitive. A passing ARC chain can only ever rescue a message that DMARC would otherwise have failed. ARC cannot cause a message to be rejected that DMARC would have passed. It is a one-directional safety valve for forwarding, not an additional gate.

It is discretionary, never mandatory. RFC 8617 does not require any receiver to honour ARC, and it deliberately does not define a trust model. Whether to act on a chain, and which sealers to trust, is left entirely to the receiver. In practice the large mailbox providers (Google, Microsoft, Yahoo) generate and consume ARC, and they weigh it together with reputation and other signals rather than treating a single cv=pass as an automatic delivery ticket. A chain sealed by a sender with poor reputation buys little.

The original sender does nothing and configures nothing. This is the crucial operational fact. You, as the domain owner publishing DMARC, do not opt in to ARC, do not publish an ARC record, and cannot make receivers honour it. ARC is implemented and trusted by the intermediaries and receivers, not by you. There is no arc= tag in your DMARC record. The best you can do is keep your own authentication clean so that the AAR at the first honest hop records a genuine dmarc=pass, which is the input ARC needs to be worth anything downstream.

How ARC shows up in your DMARC reports

Because ARC operates between mailbox providers, the place a domain owner actually observes it is in DMARC aggregate (RUA) reports. When a forwarded message fails DMARC at the final receiver but the receiver applied an ARC-based local override, the report typically records the DMARC result as fail together with a policy override reason of local_policy and a comment naming ARC. In the raw aggregate XML this looks like a <policy_evaluated> block whose <reason> has <type>local_policy</type> and a comment such as arc=pass.

Seeing that pattern is the signal that forwarding is happening and that a downstream receiver chose to trust the chain rather than enforce your reject. It tells you two useful things: the failures are forwarding-related rather than a genuine spoofing or misconfiguration problem, and at least some receivers are protecting that legitimate flow for you. Distinguishing forwarding noise from real alignment failures is exactly what report analysis is for; the DMARC report analyzer groups failures by source so you can tell a forwarder applying ARC apart from an unauthenticated source that genuinely needs fixing, and reading your first DMARC report walks through the override reasons in detail.

What ARC does not do, and where its limits are

ARC is narrow by design, and it is worth being honest about the edges.

  • ARC is not a substitute for fixing alignment. If your legitimate mail fails DMARC for a source you control, the answer is to align SPF or DKIM properly, not to hope a forwarder seals it. ARC only helps where modification by a trusted intermediary is the cause. Direct-from-source failures still need SPF and DKIM put right.
  • ARC does not establish trust; it only preserves provenance. A chain can be perfectly valid (cv=pass) and still be ignored, because the receiver does not trust the entity that sealed it. Validity and trustworthiness are separate questions.
  • ARC cannot repair a broken chain. Once cv=fail is set, no honest downstream hop can undo it. A single misbehaving or buggy intermediary in the path can poison the chain for everyone after it.
  • ARC remains Experimental. RFC 8617 is on the Experimental track, not a full Internet Standard. Adoption among the largest providers is real and meaningful, but it is not universal, and you cannot assume any given receiver honours it.
  • ARC does not change what you publish. No new DNS record on your side, no DMARC tag, no SPF or DKIM change. If you went looking for "how do I enable ARC for my domain", the honest answer is that there is nothing to enable as a sender.

The practical takeaway

ARC, as specified in RFC 8617, is a quietly elegant fix for one specific and stubborn problem: legitimate mail that fails DMARC because a trusted intermediary modified it in transit. It works by having each honest hop record the authentication verdict it saw (the ARC-Authentication-Results header), sign the message as it forwards it (the ARC-Message-Signature), and bind the whole sequence into a tamper-evident chain (the ARC-Seal, carrying the cv= chain status). A final receiver validates that chain, and if it both passes and is sealed by parties the receiver trusts, the receiver may choose to deliver a message its own DMARC check would have rejected. Permissive, discretionary, and entirely on the receiver's and intermediaries' side of the fence.

For you as a domain owner, the operational lesson is short. There is nothing to configure for ARC, and there never will be. What you control is the verdict at the first honest hop: keep SPF, DKIM and DMARC alignment clean so that the earliest ARC-Authentication-Results records a real dmarc=pass, which is the only thing that makes the chain worth honouring downstream. Then watch your aggregate reports for local_policy overrides citing ARC, so you can tell forwarding noise apart from sources that genuinely need attention.

The way to do both is to be at enforcement with healthy authentication and to actually read the reports. Confirm your published policy and alignment with the DMARC checker, keep an eye on forwarding-driven failures through the DMARC report analyzer, and if you would rather have the whole path from p=none to p=reject handled for you, with continuous monitoring and change alerts that flag exactly this kind of behaviour, our done-for-you DMARC service and ongoing monitoring do it without risking an email outage.

Share

See where your domain stands today

Run a free DMARC scan, then let us take you to enforced p=reject with no email outage.