---
title: "What is DKIM? How DKIM signatures and records work"
description: "DKIM is a signature on every email that proves which domain vouches for it and that nothing changed on the way. How it works, tag by tag, and which keys to use."
url: "https://nextmail.sh/blog/what-is-dkim"
---

[Blog](https://nextmail.sh/blog.md)[Deliverability](https://nextmail.sh/blog/tags/deliverability.md)

# What is DKIM? How DKIM signatures and records work

DKIM is a signature on every email that proves which domain vouches for it and that nothing changed on the way. How it works, tag by tag, and which keys to use.

Benjamin Nextmail team

October 31, 2026 9 min read

TL;DR

- DKIM adds a signature to every message, and the receiver checks it against a public key the signing domain publishes in DNS.
- A pass proves that the domain in the d= tag took responsibility for the message and that the signed headers and body arrived unchanged, not who wrote it or whether anyone wanted it.
- Give each service that sends for you its own selector and a 2048-bit RSA key, and rotate the key at least every six months.

DKIM, short for DomainKeys Identified Mail, is a signature the sending server adds to each message it sends. The receiving server checks it against a public key the signing domain publishes in DNS, and when the check passes it knows which domain vouches for the message and that the signed parts arrived as they left.

The standard is RFC 6376 from 2011, now a full Internet Standard. For how DKIM fits with SPF and DMARC, see [the overview](https://nextmail.sh/blog/spf-dkim-dmarc-explained.md).

## What DKIM proves, and what it does not

A valid signature proves two things:

- **The domain in `d=` took responsibility for the message.** RFC 6376 calls DKIM a way to "claim some responsibility for a message".
- **The signed parts did not change.** The body and the signed headers hash to the values they had at signing.

Nothing else. The signer need not be the author, so `d=` does not have to match the From address a person reads: a newsletter tool can sign your campaign with its own domain. Checking that the two match is the job of [DMARC](https://nextmail.sh/blog/what-is-dmarc.md).

Nor does a pass mean the mail is wanted. Spammers can sign with domains they own, so a signature only gives receivers a reliable name to attach reputation to. DKIM encrypts nothing either: the message stays as readable as before.

## How DKIM signing works

When a message leaves, the signing server:

1. **Canonicalises a copy**, a standard form used only for hashing, so harmless changes on the way do not break the signature.
2. **Hashes the body** with SHA-256 and writes the result, in base64, into `bh=`.
3. **Hashes the signed headers,** listed in order in `h=` with From always among them, followed by the new `DKIM-Signature` header with `b=` left empty.
4. **Signs** that hash with the domain's private key, puts the result in `b=` and adds the header to the message.

The `c=` tag sets canonicalisation for headers and body separately. `simple` tolerates almost no change. `relaxed` lowercases header names, unfolds wrapped lines and collapses runs of spaces, so it survives the whitespace changes servers make. Set `c=relaxed/relaxed` explicitly: a signature without `c=` is read as `simple/simple`.

## How a receiver verifies a DKIM signature

The receiver repeats the work and compares:

1. It fetches the TXT record named by the selector, then `_domainkey`, then the domain in `d=`: `s1._domainkey.example.com`.
2. It hashes the canonical body and compares the result with `bh=`.
3. It hashes the headers in `h=` and checks `b=` against that hash with the public key.

RFC 6376 names each way this can fail, and the names point at the cause:

| Result | What usually happened |
| --- | --- |
| `no key for signature` | Nothing at the selector's name: missing, misspelled or not live yet |
| `key revoked` | The record has an empty `p=` |
| `body hash did not verify` | The body changed after signing, a footer for instance |
| `signature did not verify` | A signed header changed, or DNS holds a different key |

A failed signature does not get mail refused: RFC 6376 tells receivers not to decide on it alone, and the domain's DMARC policy says what happens next.

## A DKIM-Signature header, tag by tag

A sending server adds a header like this one, shortened:

txt

```
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=s1;  t=1793404800; x=1794009600;  h=from:to:subject:date:message-id:mime-version:content-type;  bh=yQ9Ac4INleo9rDdPpDn+QbR2lLxdU1/Pkb6filuIXrU=;  b=JyW9sJyJSoF9KC8i6dl4yeMLpt7M5GJbhBKj34ydDu7bUxTFXAFJTdwHEukT5pcU...
```

| Tag | What it means |
| --- | --- |
| `v` | Version, always 1 |
| `a` | Algorithm: `rsa-sha256` or `ed25519-sha256` |
| `c` | Canonicalisation for headers, then body |
| `d` | The signing domain, taking responsibility |
| `s` | The selector, naming the key to fetch |
| `t` | Signing time, in seconds since 1970 |
| `x` | Expiry, here a week after signing |
| `h` | The signed headers, in order |
| `bh` | The hash of the canonical body |
| `b` | The signature |

Of the tags not shown, `i=` names the user the domain signs for, and `l=` limits how much of the body is signed, a risk covered below.

## The DKIM record in DNS

The public key sits in a TXT record at the selector's name:

txt

```
s1._domainkey.example.com.  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
```

| Tag | Status | What it means |
| --- | --- | --- |
| `v` | Recommended | `DKIM1`, and the first tag when present |
| `k` | Optional | The key type: `rsa`, the default, or `ed25519` |
| `p` | Required | The public key in base64. Empty means revoked |
| `t` | Optional | Flags: `y` for testing, `s` to forbid subdomains in `i=` |
| `h` | Optional | The hash algorithms allowed |
| `s` | Optional | The service: `*` or `email` |

Remove `t=y` once you are live: receivers must treat mail from a domain in testing mode exactly like unsigned mail.

### Why a 2048-bit key needs two strings

A TXT record holds text in strings of up to 255 characters, and the base64 of a 2048-bit RSA key alone is 392. So the record is published as two strings, which receivers join with nothing in between:

txt

```
s1._domainkey.example.com.  TXT  ( "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."                                   "...IDAQAB" )
```

A 1024-bit key, at 216 characters, fits in one string, but use 2048 bits wherever your DNS provider allows, as Google advises.

## RSA or Ed25519: which DKIM key to use

| Key | Status in 2026 |
| --- | --- |
| `rsa-sha1` | Banned for signing and verifying by RFC 8301 (2018) |
| RSA, 1024 bits | The minimum RFC 8301 allows and Gmail accepts |
| RSA, 2048 bits | What RFC 8301 recommends: the default to use |
| Ed25519 | Standardised in RFC 8463 (2018) and fits one TXT string, but many receivers cannot check it |

RFC 8463 requires every verifier to support Ed25519, yet Red Sift's April 2026 test of 19 mailbox providers found 9 that verified it, and Gmail, Microsoft 365, Yahoo and iCloud were not among them. Use it only as a second signature beside RSA, under its own selector, as RFC 8463 describes: a receiver that cannot check one still checks the other.

## What is a DKIM selector?

Every signature names its key with `s=`, and that name is the selector. RFC 6376 leaves the number of selectors to the domain owner, so each service that sends for a domain can sign with its own key: your mailbox provider under one selector, your newsletter tool under another.

A service can also take over a selector through a CNAME. You publish a pointer, and the service keeps the key at its end and rotates it without you touching DNS:

txt

```
s1._domainkey.example.com.  CNAME  s1.example-com.dkim.example.net.
```

### Can a domain have more than one DKIM record?

Yes, one per selector. The mistake is two TXT records at the same selector: RFC 6376 leaves the result undefined, and a receiver may use either. A new key gets a new selector.

### How do I find my DKIM selector?

Read `s=` in the `DKIM-Signature` header of a message your domain sent. DNS has no way to list the names under `_domainkey`, so a checker has to know or guess. Our [deliverability checker](https://nextmail.sh/tools/deliverability.md) tries the selectors your mail provider is known to use plus a common set, and says when a key it finds has been revoked.

## How to rotate a DKIM key

A key that signs for years has years in which to leak. M3AAWG, the messaging industry's anti-abuse group, recommends rotating at least every six months, in a guide last revised in 2019:

1. Publish the new key under a new selector and wait until DNS serves it.
2. Switch signing to the new key.
3. Keep the old key published for seven to 30 days, so mail in transit still verifies.
4. Retire it by emptying `p=`, keeping the record so receivers can see the retirement was deliberate.

Never put a new key under an old selector: RFC 6376 warns that a failure caused by the changed key then looks exactly like a forgery. Dated selectors such as `s202611` keep the order obvious.

## Why DKIM survives forwarding but not mailing lists

A forwarding server usually passes a message on unchanged, so the signature still checks out at the other end. [SPF](https://nextmail.sh/blog/what-is-spf.md) usually fails there instead, because it checks the server that hands the message over. RFC 9989, the DMARC standard published in May 2026, agrees: on a relay, "DKIM signatures will generally remain valid".

Mailing lists are different. A list that tags the subject or adds a footer changes signed content, and the signature fails. In the words of the IETF's DKIM working group, the signature of a re-posted message "typically does not survive and cannot be recovered".

List software has adapted by rewriting the From line, often to the list's own address, so DMARC is judged on a domain the list controls. ARC, the Authenticated Received Chain, was designed to make that rewrite unnecessary, but RFC 9989 notes that it has not become widely used.

## The l= tag and DKIM replay

**The `l=` tag** limits the body hash to the first so many bytes, so a list can add a footer without breaking the signature. Anything after that point is unsigned, and RFC 6376 warns that it can "completely replace the original content in the end recipient's eyes". Leave the tag out.

**Replay** works because a signature covers the message, not the envelope that says who receives it. Someone who gets one signed message, for instance by sending spam through a large provider that signs it, can resend it to thousands of new recipients, and every copy still verifies under the provider's good name. RFC 6376 offers only partial defences, such as receivers spotting one signature in unusual volume.

Senders can limit what a replayed copy may change: sign every header a reader sees, and list From, To, Subject and Date in `h=` once more than they appear, so a copy that gains a second Subject fails. A service that lets strangers send should filter what it signs: replay starts with a signature given away.

A lasting fix is in progress: the IETF's DKIM working group has adopted DKIM2, which aims to record every server a message passes through and every change each one makes, so a receiver can tell an honest forward from a replay. The group's target for sending its documents to the IESG for approval is March 2027.

## What Gmail, Yahoo and Microsoft require

Gmail and Yahoo made authentication a condition of delivery in February 2024, and Outlook.com followed in May 2025:

| Provider | Every sender | Bulk senders |
| --- | --- | --- |
| Gmail | SPF or DKIM, with a DKIM key of at least 1024 bits | Over 5,000 messages a day: SPF and DKIM, plus DMARC aligned with one of them |
| Yahoo | SPF or DKIM | SPF and DKIM, plus a DMARC record of at least `p=none` that passes |
| Outlook.com | All three strongly recommended | Over 5,000 messages a day: SPF, DKIM and DMARC |

Outlook.com refuses mail that misses the bar with `550 5.7.515`: Microsoft first planned to send it to Junk, and decided on rejection before the rules took effect. Gmail may mark unauthenticated mail as spam or refuse it with a `5.7.26` error.

## Is DKIM enough without SPF?

For DMARC, yes: one aligned pass is enough, and DKIM is the one that survives forwarding. RFC 9989 makes DKIM the one you cannot skip, because a domain at `p=reject` "MUST apply valid DKIM signatures" and must not rely on SPF alone. The large mailbox providers still want both from bulk senders, so publish both and let DMARC tie them together.

## Where Nextmail fits

Every domain you add to Nextmail gets its own signing key, and its signing record is listed with the MX and SPF records from the moment you add it. Sending switches on shortly after that record answers in public DNS. Where a record does not match yet, the domain page shows what DNS answers and the usual reason, such as a DNS provider that added your domain to the name twice.

[Connect a domain](https://nextmail.sh/docs/get-started/domain.md) has the steps, and [Domains](https://nextmail.sh/docs/knowledge/addresses/domains.md) explains how records are checked. The [deliverability checker](https://nextmail.sh/tools/deliverability.md) reads any domain's SPF, DKIM, DMARC, BIMI and MX records from live DNS and says what each one means and what is missing. The [same check](https://nextmail.sh/docs/api/tools/deliverability.md) runs over the API.

## Free tools

Try what you just read on your own setup. They are free and need no account.

[Email deliverability checker SPF, DKIM, DMARC, BIMI and MX, read live.](https://nextmail.sh/tools/deliverability.md)

- [Deliverability](https://nextmail.sh/blog/tags/deliverability.md)
- [DNS](https://nextmail.sh/blog/tags/dns.md)
- [Email authentication](https://nextmail.sh/blog/tags/email-authentication.md)

## References

1. 1 [RFC 6376: DomainKeys Identified Mail (DKIM) Signatures](https://www.rfc-editor.org/rfc/rfc6376) IETF
2. 2 [RFC 8301: Cryptographic Algorithm and Key Usage Update to DomainKeys Identified Mail (DKIM)](https://www.rfc-editor.org/rfc/rfc8301) IETF
3. 3 [RFC 8463: A New Cryptographic Signature Method for DomainKeys Identified Mail (DKIM)](https://www.rfc-editor.org/rfc/rfc8463) IETF
4. 4 [RFC 9989: Domain-Based Message Authentication, Reporting, and Conformance (DMARC)](https://www.rfc-editor.org/rfc/rfc9989) IETF
5. 5 [Domain Keys Identified Mail (dkim) working group](https://datatracker.ietf.org/wg/dkim/about/) IETF
6. 6 [DKIM Key Rotation Best Common Practices](https://www.m3aawg.org/DKIMKeyRotation) M3AAWG
7. 7 [Email sender guidelines](https://support.google.com/a/answer/81126) Google
8. 8 [Sender best practices](https://senders.yahooinc.com/best-practices/) Yahoo
9. 9 [Outlook.com Postmaster: Policies](https://substrate.office.com/ip-domain-management-snds/postmaster/Policies) Microsoft
10. 10 [Strengthening Email Ecosystem: Outlook's New Requirements for High-Volume Senders](https://techcommunity.microsoft.com/blog/microsoftdefenderforoffice365blog/strengthening-email-ecosystem-outlook%E2%80%99s-new-requirements-for-high%E2%80%90volume-senders/4399730) Microsoft
11. 11 [Ed25519 DKIM Support: Which Providers Accept Modern (and Weak) Keys?](https://redsift.com/blog/ed25519-dkim-support-weak-keys) Red Sift

Keep reading

## Related articles

Oct 31, 2026 9 min read

### What is SPF? How SPF records work and where they break

SPF is the DNS record that lists the servers allowed to send mail for your domain. How receivers check it, what each part means and what quietly breaks it.

Arta Deliverability

Oct 31, 2026 9 min read

### What is DMARC? Policy, reports and getting to p=reject

DMARC is a DNS record that checks SPF and DKIM against your visible From domain, tells inboxes what to do with mail that fails and reports who sends as you.

Arta Deliverability

Oct 31, 2026 5 min read

### SPF, DKIM and DMARC explained: how inboxes trust mail

What SPF, DKIM and DMARC each check, why alignment decides whether DMARC passes, and a safe order for moving a domain from p=none to p=reject.

Benjamin Deliverability

Try it yourself

## Your email, on your own domain.

Nextmail puts your domains, sending and inbox in one place, with the full API on every plan, the free one included.

[Open mail](https://nextmail.sh/mail/inbox) [Get Started](https://nextmail.sh/signup.md)[All articles](https://nextmail.sh/blog.md)
