Skip to main content

DKIM2: where standardization stands and how to prepare

By CaptainDNS
Published on November 3, 2025

Updated on July 27, 2026

The word DKIM2, the DKIM2-Signature and Message-Instance headers, and a chain of signed hops i=1, i=2, i=3 continued by a dashed arrow
TL;DR
  • DKIM2 is not a standard: no RFC, no document in last call, and an IETF charter schedule running about seven months late.
  • The work happens in the historic dkim working group, rechartered in February 2025. There is no "dkim2" group.
  • The current specification (draft-ietf-dkim-dkim2-spec-04, 5 July 2026) rests on two headers: DKIM2-Signature for each hop, and Message-Instance to describe modifications as JSON recipes.
  • Almost all of the 2025 syntax is gone: mv=, pp=, a=, b=, bh=, the Mail-Version: header.
  • Three implementations (Rust, Python, Go) demonstrated their interoperability in July 2026, and a fourth, in C, has been announced since: the most concrete change in a year.
  • Domain owner: nothing to do. Your keys and your _domainkey records stay valid as they are.

ℹ️ The terms DKIM replay, backscatter, Message-Instance and recipe are defined in the glossary at the end of this article.

DKIM2 has a contradictory reputation. You read that it will replace DKIM "soon", that it will make DMARC obsolete, or, on the contrary, that it exists only on paper. The reality of July 2026 is simpler: the protocol is still not standardized, but it has stopped being theoretical, since three independent implementations now sign, verify and rebuild messages together.

Why does DKIM2 exist?

DKIM (STD 76, RFC 6376) signs the content of a message. That is its strength and, after twenty years in production, its limit: the signature says nothing about the path taken or the addresses actually used at each SMTP hop.

The replay gap DKIM does not close

An attacker who obtains a legitimately signed message can re-send it at scale without touching anything the signature covers: the signature stays valid, DMARC keeps passing, and the signing domain is the one that absorbs the degraded reputation. That is DKIM replay, and no key rotation truly eliminates it.

Forwarding that breaks the signature

A mailing list that adds a footer, prefixes the subject or inserts an unsubscribe header invalidates the signed hash. DKIM offers no way to describe the modification, and therefore no way to reverse it and check the original signature.

Bounces that go back to a third party

When a server accepts a message and then generates a bounce after the fact, that bounce goes to the envelope address, which may be spoofed. That is backscatter: an innocent victim receives non-delivery reports for mail they never sent.

DKIM2 tackles all three at once: each hop adds its own numbered signature, declares the envelope it used, and documents what it modified. The path becomes verifiable and the modifications reversible.

DKIM2 signature chain: each SMTP hop adds a numbered signature that declares the envelope used

Is your current DKIM healthy before you even think about DKIM2?

Where does standardization stand?

One rechartered group, three documents

There is no "dkim2" working group at the IETF, and that is the first source of error. The work takes place in the historic dkim group, chaired by Murray Kucherawy and Pete Resnick; the IESG approved its revised charter on 20 February 2025.

Three working group documents are active:

  • draft-ietf-dkim-dkim2-spec-04 (5 July 2026), Standards Track, 43 pages, expires on 6 January 2027. Authors: Richard Clayton (Yahoo), Wei Chuang (Google), Bron Gondwana (Fastmail).
  • draft-ietf-dkim-dkim2-bcp-00 (18 June 2026), Todd Herr. Adopted, but deliberately put on hold until the group has accumulated operational experience.
  • draft-ietf-dkim-dkim2-dns-00 (20 July 2026), Wei Chuang.

What the schedule says

None of these documents is in working group last call, none has been submitted to the IESG, and no RFC exists. Yet the charter milestones targeted "all documents submitted to the IESG by 31 December 2025": the delay is about seven months, and the schedule has not been revised.

There have been few real milestones over the past period. November 2025: the motivation, header and mailversion drafts stop being maintained. 20 March 2026, at IETF 125: Richard Clayton's specification becomes the main document and the JSON format is retained to describe modifications. 24 March 2026: first working group draft of the specification. 24 June 2026: spec-03 introduces the nd= tag. 24 July 2026: DKIM session at IETF 126, in Vienna.

The dead documents

Any content written in 2025 about DKIM2 points to drafts that have since been abandoned or replaced: always check the names and the revisions it cites. draft-ietf-dkim-dkim2-motivation-02 has expired; draft-ietf-dkim-dkim2-header-00 and draft-gondwana-dkim2-mailversion-00 are marked "Dead WG Document". Their content has been absorbed, rewritten or abandoned.

Another error in circulation: several publications claim that the group adopted a "milter deployment profile". That is false. On 8 May 2026, the group chair wrote that "the working group does not wish to pursue adoption at this time".

DKIM2 timeline: from the abandonment of the 2025 drafts to the publication of spec-04 and the IETF 126 session

What DKIM2 changes in practice

The mechanism rests on two distinct headers.

The DKIM2-Signature header

Each hop adds a line. Section 8 of the specification sets the requirements: "The i=, m=, t=, d= and s= tags MUST be present. There MUST be either an nd= tag or both mf= and rt= tags. The other tags are optional."

TagRequiredRole
i=yesHop sequence number. The original sender signs with i=1, and each subsequent hop increments it. A single gap in the numbering and the whole message is treated as unsigned.
m=yesHighest Message-Instance number at the time of signing.
t=yesTimestamp, expressed in UTC epoch seconds (an integer, not a formatted date).
d=yesSigning domain. It is the one used to build the DNS query that fetches the key.
s=yesselector:algorithm:base64-signature triplet.
mf=conditionalMAIL FROM used at sending time, base64-encoded, angle brackets included.
rt=conditionalRCPT TO, base64, angle brackets included. Several recipients can be listed.
nd=conditionalDomain that will sign the next hop. Mutually exclusive with mf= and rt=.
n=noFree-form nonce, 64 characters at most.
f=noFlags.

The s= tag follows the ABNF sig-set = selector ":" sig-name ":" message-sig, where sig-name is either rsa-sha256 or ed25519-sha256; several signatures using different algorithms can coexist, but "a different selector MUST necessarily be used for each signature". The d= tag itself must exactly match the rightmost labels of the domain carried by mf=: in other words, d= is either identical to that domain or one of its parent domains. So mf=<user@mail.example.com> goes with d=example.com, whereas the reverse, mf=<user@example.com> with d=mail.example.com, is rejected. Only an empty mf=, that is <>, as used for non-delivery reports, is exempt from that match.

On the cryptography side, the specification mandates RSA of at least 1024 bits for signing and requires verifiers to accept 1024 to 2048 bits; support for larger keys is optional. The public exponent is 65537, the padding PKCS#1 v1.5, the hash untruncated, SHA256 mandatory, and Ed25519 in the PureEdDSA variant (RFC 8032, section 5.1): "Signers SHOULD implement both RSA-SHA256 and Ed25519-SHA256, Verifiers MUST implement both". A signature more than 14 days old may be ignored, but that is a MAY, not a requirement.

The f= flags have been reworked. exploded indicates that the message is going to more than one address; its absence lets an MTA assume that a single copy exists, and that is precisely the anti-replay lever. donotexplode and donotmodify are prohibitions addressed to intermediaries. feedback requests a response, and its absence means that response is not wanted; feedhere lets an intermediary relay that response without revealing the final destination. Any unknown flag must be ignored.

A verifier produces one of the four states PASS, FAIL, PERMERROR or TEMPERROR, aligned with RFC 8601.

The Message-Instance header

The second header describes the state of the message and the means of returning to the previous one: "The m= and h= tags MUST be present. The r= tag is optional."

The m= tag is the revision number: it starts at 1 and is incremented with each new instance; a gap makes the message unverifiable. The h= tag takes the form sha256:<header hash>:<body hash>, both in base64, and several sets can coexist. The r= tag contains "the base64 encoded version of the JSON object that contains the recipes that allow the previous instance of the message to be recreated".

An important point for operators: if you modify nothing, you do not add a Message-Instance; a relay that passes the message on unchanged has nothing to describe.

The recipes form a JSON object, identified by the schema https://dkim2.org/schemas/recipe-v1, with a key "h" for the headers and/or "b" for the body. Each recipe is an array of steps carrying exactly one key: {"c": [start, end]} copies a range of lines or instances, {"d": ["..."]} emits literal data. A "b": null signals a previous body that cannot be rebuilt; an empty array associated with a field name means "delete all its instances". A classic trap: headers are numbered from bottom to top, body lines from top to bottom.

Your DNS keys do not change

The public key is fetched at <selector>._domainkey.<d=>, exactly as it is today: "these keys are no different, and are stored in the same locations as those for DKIM1". No new record type, no DNS migration to prepare.

Anatomy of a DKIM2-Signature header and of a Message-Instance, tag by tag

nd= or mf=/rt=: the chain of custody

A sequence of several DKIM2-Signature headers carrying nd= is allowed, but it "MUST end with a DKIM2-Signature that contains mf= and rt= tags", and the domain declared in nd= must match exactly the d= of the next signature in i= order.

Section 9.3 presents this variant as a chain of custody for imaginary hops. Take a system that receives mail on one domain and re-sends it from another: the continuity between the rt= of the previous hop and the mf= of the next one is broken. Rather than fabricating a signature with invented mf= and rt= values, which would pollute the chain with fictitious addresses, the system announces with nd= who the next signer will be. That is the option the specification encourages.

Sample headers

spec-04 contains no example of a message or a header: the draft that was meant to provide them, draft-robinson-dkim2-message-examples-00, expired in 2025. The example below is therefore reconstructed from the ABNF grammar of the document, and has no normative value.

A two-hop scenario: a sender writes to a mailing list, the list adds a List-Unsubscribe header and re-sends.

DKIM2-Signature: i=2; m=2; t=1740001000; d=test2.dkim2.com;
  mf=PGJvdW5jZUB0ZXN0Mi5ka2ltMi5jb20+; rt=PHJlY2lwaWVudEBleGFtcGxlLmNvbT4=;
  s=ed25519:ed25519-sha256:FDYZopU8W+c7...;
DKIM2-Signature: i=1; m=1; t=1740000000; d=test1.dkim2.com;
  mf=PHNlbmRlckB0ZXN0MS5ka2ltMi5jb20+; rt=PGxpc3RAdGVzdDIuZGtpbTIuY29tPg==;
  s=ed25519:ed25519-sha256:oKZmf7rabJv4...;
Message-Instance: m=2; h=sha256:u4RFAizDeEqt...:SgG5fNGEg1x2...;
  r=eyJoIjp7Imxpc3QtdW5zdWJzY3JpYmUiOltdfX0=;
Message-Instance: m=1; h=sha256:SLtzk6LO68CC...:SgG5fNGEg1x2...;
Received: from test1.dkim2.com by relay.example.com; ...
List-Unsubscribe: <mailto:unsub@relay.example.com>
From: sender@test1.dkim2.com
To: list@test2.dkim2.com
Subject: ...

Let us decode it. The envelope values are in base64, angle brackets included, as the specification requires. At the first hop, mf= is <sender@test1.dkim2.com> and rt= is <list@test2.dkim2.com>. At the second, the list re-sends: mf= is <bounce@test2.dkim2.com> and rt= is <recipient@example.com>. The continuity of the chain is visible to the naked eye, and that is the whole point of the mechanism.

The most instructive part is the r= of Message-Instance number 2. Decoded from base64, it gives:

{"h":{"list-unsubscribe":[]}}

In plain English: "to go back to the previous instance, delete every occurrence of the List-Unsubscribe field". A verifier that wants to validate the i=1 signature applies this recipe, recovers the message as the sender sent it, recomputes the hash and compares. The modification did not break the chain: it was declared and made reversible.

The s= values and the h= hashes are truncated: they would depend on private keys and on a real message, so the reader cannot recompute them. The example is there to show the structure of the headers, not to be verified.

What has changed since the 2025 drafts

If you read a DKIM2 guide published in late 2025, just about all the syntax it described is gone.

2025 elementStatus in spec-04
Single DKIM2: header (Active/Historical)Removed, replaced by the DKIM2-Signature and Message-Instance pair
Mail-Version: headerRemoved, reworked into Message-Instance; compact recipes give way to base64-encoded JSON
mv=Renamed m=
v=Does not exist and never will
pp= (proxy signing)Removed; nd= has taken its place since spec-03 (24 June 2026)
a=Removed, merged into s=
b=Removed, absorbed by s=
bh=Moved into the h= of Message-Instance
h= (list of signed fields)Meaning inverted: DKIM2 signs everything except an exclusion list
t=Goes from a formatted date-time to an epoch integer
f=modifiedbody, f=modifiedheaderRemoved, deemed redundant with the version data
f=donotforwardRemoved
f=feedhereNew, appeared in spec-03

The absence of v= is deliberate

Section 8 justifies it: "Experience from IMF onwards shows that it is essentially impossible to change version numbers. If it becomes necessary to change DKIM2 in the sort of incompatible way that a v=2 / v=3 version number would support, it is expected that header fields will be labelled as DKIM3 instead." A major break would therefore produce a DKIM3-Signature header, not an internal version number.

The inversion of h=

DKIM enumerates the fields it signs. DKIM2 does the opposite: it signs everything, except seven families of fields listed in section 4.1, namely ARC-*, Authentication-Results, Delivered-To, DKIM-Signature, Received, Return-Path and X-*. Exactly the fields an intermediary legitimately needs to add or modify in transit.

ARC heads into retirement

ARC addressed the same symptom: forwarding breaks SPF and DKIM. But it merely carried a sealed record of the authentication results observed before the relay, without ever closing the replay gap. That is traceability, not end-to-end integrity. The IETF is now reclassifying it as "Historic" and concentrating the effort on DKIM2, which treats the cause rather than the symptom. The details of that reclassification and its practical consequences are covered in a dedicated article.

Where do the implementations stand?

This is where the year proved decisive: we went from zero implementations to three that understand each other, and a fourth has been announced since.

On 4 July 2026, an interoperability demonstration brought together three independent implementations: mail-auth in Rust (Stalwart Labs), Bron Gondwana's Python implementation, and Steve Atkins's Go implementation. Signing, verification and recipe-based reconstruction were tested in both directions, including on multi-hop chains. Announced result: with header folding disabled, every combination passes. Two folding bugs were identified along the way, one on the Go side (strict base64, without whitespace stripping), the other on the Python side (splitting on : without unfolding first).

On 8 July 2026, Bron Gondwana centralized the test suite in the dkim2wg GitHub organization and mentioned a fourth implementation, in C (PhoenixDKIM).

On timing, forecasts do exist, dated and attributed. Laura Atkins (Word to the Wise, 23 April 2026) writes: "We should have working DKIM2 from the major providers by the end of 2026". Al Iverson (Spam Resource, 21 April 2026) recalls that "the specification is not yet finalized. Things are subject to change", and, on the keys: "Keys aren't changing (at least not so far)". No primary source announces a mandatory date for senders, and the mandate timelines in circulation are backed by no primary source.

State of the IETF dkim working group documents and of the three DKIM2 implementations that demonstrated their interoperability

What is not settled yet

The group met at IETF 126, in Vienna, on 24 July 2026. The following points were raised there, not decided; the minutes of the session have not been published yet.

  1. Null recipes for headers: should they be removed, for lack of an identified use case?
  2. Bogus Message-Instance: the current MUST NOT rules are too strict and caused message rejections during the interoperability tests.
  3. Post-quantum algorithm: the group is seeking expert advice; the difficulty identified is that very long keys travel badly in DNS over UDP.
  4. Case of field names: should lowercase be mandated in the JSON recipes?
  5. Non-delivery reports: should there be a dedicated flag, and should Message-Instance be omitted?
  6. Alignment and DMARC: "The DKIM2 spec deliberately stays away from saying anything about DMARC", and the topic is deferred to the best practices document. The expectation expressed is an alignment between the original From:, the initial MAILFROM and the d= of the first DKIM2-Signature, whereas DKIM2 today only requires the last two to align.
  7. Messages relayed with DKIM1 only: should they be signed with DKIM2?
  8. Feedback loops: should their format be standardized?

That list is the best measure of the protocol's real maturity, and the reason why the best practices document stays frozen.

Operational impact

The consequences are not the same depending on your role, and the split is lopsided.

Domain owner: nothing to do

No action to take today. The only useful thing is to keep a healthy DKIM1, with a key rotation you control, and a DMARC policy in place: that is the foundation DKIM2 will build on.

A clarification that comes up often: DMARC is not going away. It retains value of its own, in particular domain-level aggregate reports and detection of spoofing of the From: domain, neither of which DKIM2 replicates.

ESPs, relays and mailing lists: the real work

Signing at every hop, tracking modifications as recipes, and above all anticipating an underestimated side effect: the influx of inbound asynchronous bounces. DKIM2 sends the message back to the previous hop, which changes the volume and the nature of the returns to handle, a point Laura Atkins stresses in particular.

Another point to watch: double signing (the brand's and the platform's), as it is practiced today in DKIM, does not transpose directly. Al Iverson noted on 9 May 2026: "No such thing as multiple signatures, directly, I think".

Verifiers: start from the top

Verification runs counter to intuition: you start from the highest i=, the most recent signature, then walk back up the chain applying the recipes to rebuild the previous instances.

DNS location of the DKIM2 keys under _domainkey, identical to the one used by DKIM1

Readiness plan

  1. Inventory your flows: where you sign, where you verify, which intermediate hops exist, which envelope-rewriting mechanisms (SRS, VERP) are in place.
  2. Clean up DKIM1: up-to-date selectors, keys of a correct size, documented rotation.
  3. Prototype on the relay side if you run one: mf= and rt= in base64 with angle brackets, i= numbering, epoch timestamp, choice of algorithms.
  4. Model your common modifications as JSON recipes: footer, subject prefix, List-Unsubscribe. That is the exercise that reveals the hard cases.
  5. Size the handling of inbound asynchronous bounces, the point most often forgotten.
  6. Do not touch your DNS for DKIM2: there is nothing new to publish.
  7. Set up a watch on draft-ietf-dkim-dkim2-spec and plan feature flags: four revisions in a little over three months, the syntax is still moving.

FAQ

Is DKIM2 a standard in 2026?

No. As of 25 July 2026, there is no DKIM2 RFC: the specification is at the draft-ietf-dkim-dkim2-spec-04 stage, published on 5 July 2026, and no working group document is in last call or submitted to the IESG. The charter milestones targeted a submission by 31 December 2025, which means a delay of about seven months.

Do I have to change my DNS records for DKIM2?

No. The specification states that DKIM2 keys are no different and are stored in the same locations as DKIM1 keys, under selector._domainkey.yourdomain. No new record type, no DNS migration to plan.

What is the difference between DKIM2-Signature and Message-Instance?

DKIM2-Signature is added by every SMTP hop: sequence number i=, timestamp, signing domain, signature and envelope used. Message-Instance describes the state of the message and the means of returning to the previous one, through JSON recipes encoded in base64 in the r= tag. An intermediary that modifies nothing adds a signature, but no Message-Instance.

Does DKIM2 replace DMARC?

No. DMARC retains value of its own that DKIM2 does not replicate: domain-level aggregate reports and detection of spoofing of the From: domain. The specification also deliberately avoids saying anything about DMARC and defers the alignment question to the best practices document.

Are there working DKIM2 implementations?

Yes: three implementations have demonstrated their interoperability, and a fourth has been announced since without taking part in the demonstration. On 4 July 2026, an interoperability demonstration brought together mail-auth in Rust (Stalwart Labs), a Python implementation by Bron Gondwana and a Go implementation by Steve Atkins, including on multi-hop chains. A fourth implementation in C, PhoenixDKIM, was mentioned afterward, on 8 July 2026, when the test suite was centralized in the dkim2wg GitHub organization.

What should I do today if I simply run a corporate domain?

Nothing specific to DKIM2: check that your current DKIM is correctly published and signed, that your DMARC is in place and monitored, and that your key rotation is documented. The real migration work concerns ESPs, relays and mailing lists, not domain owners.

📖 Glossary

DKIM replay

Mass re-sending, or re-sending to other targets, of a message already signed by a legitimate domain, without altering anything the signature covers: the signature stays valid, because DKIM signs the content but neither the SMTP envelope nor the route. The signing domain sees its reputation degrade for mail it never sent, and no DKIM1 mitigation (rate limiting per selector, key rotation, stricter DMARC) closes the gap. In DKIM2, the signature includes the envelope of the hop and chains the path through the i= number.

Backscatter

Unwanted bounces (NDR, DSN) or auto-replies sent to an innocent third party whose address was spoofed in MAIL FROM or Return-Path: their mailbox is flooded with non-delivery reports. In DKIM1, you reject during the SMTP exchange rather than afterward, with SRS or VERP to trace bounces; in DKIM2, the returns walk back up the signed chain to the previous hop, and therefore toward an actor genuinely involved.

Message-Instance

A DKIM2 header describing the state of a message at a point in its journey: m= (revision number) and h= (hash of the headers and of the body) mandatory, r= (recipes) optional.

Recipe

A JSON description, base64-encoded in the r= tag of a Message-Instance, that makes it possible to rebuild the previous instance of the message.

Sources

DKIM2 remains a work in progress. This page will be updated as the specification draft goes through its revisions.

Verify your current DKIM

It is your current DKIM setup (RFC 6376) that will be reused. Inspect your live selectors with the DKIM Record Checker and validate the syntax of every published record with the DKIM Syntax Validator.

Similar articles