How to rotate DKIM keys without breaking mail
A safe DKIM key rotation: why and how often, 2048-bit RSA keys, two selectors with an overlap period, revoking with an empty p= and provider-hosted keys.
By Exmoor Software6 min read
A DKIM key that never changes becomes a liability: the longer it is in use, the more places its private half has been copied to and the longer a leaked copy stays useful. Rotating the key means replacing the key pair your mail is signed with — without a single message failing verification along the way.
The trick is the selector. You publish the new key under a new name, switch signing to it, and retire the old key only after mail signed with it has had time to be verified. If you need a refresher on signatures and selectors, start with How DKIM works.
Why rotate at all
- A leaked private key lets anyone sign as you. RFC 6376 (section 8.3) is blunt about it: whoever holds the private key can send mail signed by your domain, and that mail passes DKIM — and DMARC. Rotation limits how long a leaked key stays useful.
- Old keys are often too short. RFC 8301 made 1024 bits the minimum and 2048 bits the recommendation. Rotation is how you replace old 1024-bit keys.
- People and vendors change. Administrators leave, contracts with sending services end.
- Practice. M3AAWG recommends rotating at least every six months, partly so that the procedure is routine on the day you need it in a hurry.
Choose the new key
Use RSA with 2048 bits, signing with rsa-sha256. RFC 8301 requires signers to use at least 1024 bits, recommends at least 2048, requires verifiers to handle keys from 1024 to 4096 bits, and forbids rsa-sha1 for signing and verifying.
A 2048-bit public key is about 400 base64 characters — more than one TXT string can hold (255). The record is split into several strings, which are joined without spaces before use (RFC 6376, section 3.6.2.2). Many DNS panels split long values for you; others need you to enter the strings yourself.
You can generate the key pair with the same OpenSSL commands RFC 6376 uses in its appendix, with 2048 bits instead of 1024:
openssl genrsa -out s202610.private 2048
openssl rsa -in s202610.private -pubout -out s202610.public
The p= value is the content of s202610.public without the BEGIN and END lines, joined into one line. Many mail servers and signing tools generate the key and the ready-to-publish record for you. If you also sign with Ed25519 keys (RFC 8463), rotate them the same way, each under its own selector.
Selectors make the overlap possible
A key is published at selector._domainkey.domain, and every signature names its selector in s=. Because any number of selectors can exist side by side, the old and the new key can be published at the same time (RFC 6376, section 3.1). Two rules follow:
- A new key gets a new selector. RFC 6376 advises against reusing a selector for a new key, because you could no longer tell a message signed with the old key from a forged one. M3AAWG adds that verifiers may still have the old key cached.
- Use a naming scheme. A selector that says when the key went live —
s202610for October 2026 — makes audits easy. M3AAWG suggests including the date, and optionally the mail stream and key length.
Step-by-step rotation
In this example, example.com signs with selector s202604 and moves to s202610.
-
Generate the new key pair. The private key stays on the signing system only.
-
Publish the public key under the new selector:
s202610._domainkey.example.com. 3600 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA…" "…IDAQAB" -
Check the record before you sign with it. The DKIM checker with selector
s202610shows the key type and length and catches strings that were joined incorrectly. A brand-new name is usually visible quickly, because no resolver has cached it — unless something queried it before you published it; then the cached “does not exist” answer can linger for the zone’s negative-caching time. The DNS propagation checker compares public resolvers. -
Switch signing to
s202610in your mail server or signing service. Leave the old key published. -
Verify on real mail. Send a message to an external mailbox and paste its headers into the email header analyzer: the
DKIM-Signatureshould shows=s202610and Authentication-Resultsdkim=pass. In the following days, DMARC aggregate reports list the selector of every signature, so you can see whether any system still signs with the old one. -
Wait. Receivers don’t always verify at delivery time. RFC 6376 (section 5.2) says the old public key should stay published for a reasonable validation interval; M3AAWG recommends at least seven days and up to 30.
-
Revoke the old key by emptying
p=:s202604._domainkey.example.com. 3600 IN TXT "v=DKIM1; p="An empty
p=means the key has been revoked; verifiers treat signatures that use it as failed. RFC 6376 sees no semantic difference between a revoked key and a removed record, but M3AAWG recommends keeping the revoked record so that it is visibly retired. -
Destroy the old private key.
| When | Action | Published keys |
|---|---|---|
| Day 0 | publish s202610 | s202604 (signing), s202610 |
| Day 1 | switch signing | s202604, s202610 (signing) |
| Day 8–31 | revoke s202604 | s202604 revoked, s202610 (signing) |
M3AAWG adds a useful habit: publish the next key in advance. With a spare selector already in DNS, an emergency rotation is just a configuration change on the signing side.
TTLs
During a normal rotation the TTL hardly matters, because you add a new name and change the old one only weeks later. It matters in two situations:
- Emergency revocation. Resolvers that cached the old key keep serving it until its TTL expires. Keep the TTL of key records moderate — for example 3600 seconds — so a revocation takes effect within hours, not days.
- Changing a key in place. If you put a new key behind an existing selector, caches keep serving the old key and new signatures fail until the TTL runs out. That is one more reason to use a new selector every time.
If a key is compromised
- Switch signing to the pre-published spare selector, or publish a new key and switch as soon as it is visible.
- Revoke the compromised selector immediately with
p=. Messages signed with it that are still in transit will fail DKIM; if your SPF is aligned, they can still pass DMARC. - Find out how the key leaked before the new one goes the same way.
Keys hosted by your provider (CNAME)
Many services don’t hand you a key to publish. They ask for CNAME records that point to keys they host:
esp1._domainkey.example.com. 3600 IN CNAME esp1.example-com.dkim.esp.example.net.
esp2._domainkey.example.com. 3600 IN CNAME esp2.example-com.dkim.esp.example.net.
The provider can then rotate keys by changing what it publishes at its end, with no change in your DNS. Two or more CNAMEs let it keep the old and the new key published side by side; M3AAWG describes this delegation model with three entries.
Microsoft 365 uses two CNAMEs, selector1._domainkey and selector2._domainkey. You start a rotation in the Microsoft Defender portal or with Rotate-DkimSigningConfig in Exchange Online PowerShell; the new key starts signing after four days (96 hours). A configuration created in PowerShell defaults to 1024-bit keys; Rotate-DkimSigningConfig -KeySize 2048 moves to 2048 bits, starting with the selector that becomes active at that rotation.
Google Workspace gives you a TXT record to publish yourself, with the default selector (prefix) google; choose 2048 bits if your DNS host supports it. The setup page lets you pick a different prefix, so a new key doesn’t have to replace the old record in place — follow Google’s current instructions for the switch.
With hosted keys, watch for two things:
- Keep all the CNAMEs while the service sends for you. Microsoft notes that without the
selector2record, key rotation fails. - Remove the CNAMEs when you leave a service. Otherwise it still controls a valid signing key for your domain.
The DKIM checker follows CNAME delegation, so you can confirm the length of a provider-hosted key after each rotation.
Before your first rotation
- Inventory your selectors. DNS can’t list the names under
_domainkey, so collect them from thes=tag in mail from each sending system, or from the DKIM entries in your aggregate reports — see How to read DMARC aggregate reports. - Record for each system who holds the private key, the key length and the date of the last rotation.
- Put the next rotation in the calendar.
References
- RFC 6376 — DomainKeys Identified Mail (DKIM) Signatures
- RFC 8301 — Cryptographic Algorithm and Key Usage Update to DKIM
- RFC 8463 — A New Cryptographic Signature Method for DKIM (Ed25519)
- M3AAWG — DKIM Key Rotation Best Common Practices (2019)
- Microsoft Learn — How to use DKIM for email in your custom domain
- Google Workspace Admin Help — Set up DKIM