How DKIM Works
DomainKeys Identified Mail (DKIM) lets a domain owner cryptographically sign outgoing messages so that receivers can verify two things: the message genuinely came from someone with control over the domain, and the body and selected headers have not been altered in transit. Unlike SPF, the DKIM signature travels with the message — meaning it survives forwarding, mailing lists, and other intermediate handlers that break SPF.
The signing process
When an outgoing message leaves an SMTP server configured for DKIM, the server does roughly the following:
- Canonicalize the headers and body. Canonicalization normalizes whitespace, casing of header names, and trailing newlines so that minor formatting differences during transit do not break the signature. Two canonicalization modes are commonly used:
simple(strict) andrelaxed(lenient — the practical default). - Hash the body. Compute a SHA-256 hash of the canonicalized body. The hash is included in the signature as the
bh=parameter. - Build the signed header set. Concatenate the canonicalized form of a chosen set of headers (typically From, To, Subject, Date, Message-ID, MIME-Version, Content-Type, and the DKIM-Signature itself with its
b=field temporarily empty). - Sign with the private key. RSA-SHA256 or Ed25519 signature over the canonicalized header set, including the body hash. Place the signature in the
b=field of the DKIM-Signature header.
The resulting DKIM-Signature header is prepended to the message. The receiver can verify it by repeating the canonicalization, fetching the public key from DNS, and checking the signature.
What a DKIM signature header looks like
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=mail2026; t=1716643200;
h=from:to:subject:date:message-id;
bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
b=K3KqDfM2gG4z/m...truncated...0NX==
Field reference:
v=1— DKIM version. Always 1.a=rsa-sha256— signing algorithm.rsa-sha256(RFC 6376) ored25519-sha256(RFC 8463).c=relaxed/relaxed— canonicalization mode for headers and body, respectively.d=example.com— the signing domain. Used to construct the DNS lookup.s=mail2026— the selector. Used together withd=for the lookup path.t=1716643200— Unix timestamp the signature was created.h=from:to:subject:...— colon-separated list of headers that were signed.bh=...— base64 SHA-256 hash of the canonicalized body.b=...— the actual signature, base64 encoded.
How selectors and DNS work together
The combination of s= and d= tells the receiver exactly where to find the public key in DNS:
selector._domainkey.signing-domain
mail2026._domainkey.example.com
The receiver looks up that TXT record. Example response:
mail2026._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
Field reference:
v=DKIM1— version tag.k=rsa— key type.rsaored25519.p=...— base64-encoded public key. An emptyp=means the key is revoked and the receiver should treat any signature from this selector as invalid.t=y(optional) — testing mode flag. Receivers may treat signatures as advisory only.s=email(optional) — service type restriction.
Why selectors exist: they let a single domain publish multiple keys simultaneously. You can have s1.example.com, s2.example.com, and a vendor-specific selector like sendgrid._domainkey.example.com all active at once. Multiple selectors are the foundation of safe key rotation.
Why DKIM survives forwarding (mostly)
SPF fails on forwarding because the forwarder's connecting IP is not in the original sender's authorized list. DKIM has no IP dependency — the signature is computed from the message itself and verified against a public key in DNS. As long as the message body and signed headers are not modified, the signature still verifies regardless of how many hops the message takes.
The "mostly" caveat: some intermediaries do modify messages. Mailing list software prepends [List-Name] to subjects, appends unsubscribe footers, and rewrites From: addresses to bypass DMARC. Anti-spam gateways add disclaimer footers. Any of these modifications change the canonicalized signed content and invalidate the signature. RFC 8617 (ARC — Authenticated Received Chain) was designed to solve this by letting intermediaries vouch for what the original signatures said, but adoption is partial.
Key rotation: the only safe procedure
Keys must be rotated periodically — every six months is the common cadence, and any time a key may have leaked is mandatory. The wrong way to rotate is to generate a new key and overwrite the old DNS record. In-flight messages signed with the old key will fail verification when receivers look up the (now-new) public key.
The correct rotation uses a second selector:
- Generate a new keypair.
- Publish the new public key under a new selector (e.g.,
2026q3._domainkey.example.com) in DNS. - Wait for DNS propagation (15-60 minutes).
- Switch the signing server to use the new selector and private key for outgoing mail.
- Wait at least 7 days. This guarantees the old key is no longer signing any new messages, and any in-flight messages signed by the old key have either been delivered or expired.
- Remove the old DNS TXT record (or publish it with
p=empty to mark it revoked).
Key length and algorithm choice
RSA-1024 was the original DKIM recommendation but is now considered weak. All modern signing should use at least RSA-2048. Some major receivers downgrade or skip verification of RSA-1024 signatures entirely.
Ed25519 (RFC 8463) is faster, produces much shorter signatures, and has stronger security per bit. The trade-off is compatibility — about 80% of major receivers verify Ed25519 in 2026, but the long tail of smaller receivers may not. The defensive setup is to publish both an Ed25519 and an RSA-2048 selector and have the sending server include both signatures on every message. Receivers verify whichever they support.
Debugging DKIM failures
- Read the Authentication-Results header. Look for
dkim=. Example:dkim=fail (signature did not verify) header.d=example.com header.s=mail2026. The reason in parentheses points to the exact problem. - Verify the public key resolves. Run
dig +short TXT mail2026._domainkey.example.com— you should get a single record starting withv=DKIM1. An empty result means DNS misconfiguration. Multiple records mean a parsing problem on receivers. - Check for modification. If the signature verifies on local test sends but fails after passing through a mailing list or forwarder, an intermediary is modifying the message. Look for added footers, modified subjects, or appended attachments.
- Confirm the key matches. Use an online DKIM record validator (MXToolbox, EasyDMARC). The validator parses the DNS record and confirms it is syntactically valid and the encoded key is well-formed.
- Test signing locally. Tools like
opendkim-testkeyverify that your local private key matches the published public key — useful when rotating keys.
Frequently Asked Questions
What key size should I use for DKIM?
2048-bit RSA is the current standard. 1024-bit RSA was the original recommendation but is now considered weak and is being phased out by major receivers. Some operators use Ed25519 keys (RFC 8463) which are shorter and faster, but support is not yet universal — about 80% of major receivers verify Ed25519 in 2026. For maximum compatibility, publish both an RSA-2048 and an Ed25519 selector and let receivers pick.
How often should I rotate DKIM keys?
Every six months is the industry standard. The rotation process uses two selectors: publish the new key under a new selector, wait until the old key has not signed any mail for at least 7 days, then remove the old DNS record. This zero-downtime rotation is the only safe way to change a key. Never just overwrite an existing selector — in-flight messages signed with the old key will fail verification.
What is a DKIM selector?
A selector is a label that lets a single domain have multiple DKIM keys. The selector appears in the DKIM-Signature header (s=selector1) and in the DNS lookup path (selector1._domainkey.example.com). Multiple selectors enable key rotation, separate keys per sending service, and per-environment keys. There is no functional restriction on selector names; conventions like s1, dkim1, mail, google are all common.
Why does my DKIM signature fail after the message reaches the inbox fine?
This usually means the message was modified after signing. Mailing list software, signature appenders, antivirus footer additions, and some forwarding setups rewrite or append to the message body — invalidating the body hash that DKIM signed. The receiver still delivers the message but reports DKIM=fail in Authentication-Results. The fix is server-side: configure the modifying service to either not modify, or to re-sign with its own DKIM key after modifying.
Can I have multiple DKIM signatures on one message?
Yes. A message can carry any number of DKIM-Signature headers, each referencing a different signing domain and selector. Many transactional providers add their own DKIM signature in addition to your customer-domain signature. For DMARC, at least one signature must pass and align with the From: domain. The other signatures still verify normally but do not affect DMARC if they do not align.
Related Guides
More From This Section
All Email Guides
SPF, DKIM, DMARC, MX records, deliverability, and email headers.
DNS Records for Email
The complete DNS-record checklist for a mail-sending domain — MX, SPF, DKIM, DMARC, MTA-STS, TLS-RPT, BIMI, and reverse…
SPF, DKIM, DMARC: How Email Authentication Works
SPF, DKIM, and DMARC explained in plain English — how the three email authentication standards work together, what each…
Run a Speed Test
Measure download, upload, ping, and jitter in your browser.