Rotating a DKIM key looks like it should be one DNS edit. Generate a new key pair, paste the new public key over the old one, restart the signer. That version works right up until a message signed an hour earlier finally reaches its destination and fails authentication, because the name in its signature now resolves to a different key.
DKIM is built so that never has to happen. The mechanism is the selector, and once you see what a selector does, a rotation becomes a short sequence of steps with one long wait in the middle.
Why a DKIM key has a lifetime#
Nothing in DKIM expires a key. A record published years ago keeps verifying signatures for as long as it stays in DNS. The lifetime is a policy you impose, and there are four ordinary reasons to impose one.
- The private key can leak. It sits on a mail server, in a configuration file, and in backups. Anyone who obtains a copy can sign mail that your domain vouches for, and every check passes, because as far as the receiver can tell the message really was signed by your key.
- The key may be too short. RFC 8301 requires signers to use RSA keys of at least 1024 bits and says they should use at least 2048. Verifiers must handle 1024 through 4096 bits, and must not accept a signature from a key shorter than 1024. A 1024-bit key is the floor the spec tolerates, not the size it recommends.
- You are changing who sends your mail. The old provider's key should not stay authorised once they stop sending for you.
- You want to bound the damage. A rotation schedule puts a ceiling on how long an unnoticed leak stays useful.
The same RFC settles a neighbouring question: rsa-sha1 must not be used for signing or verifying. If the record you are replacing offers SHA-1 as its only hash, fix that too.
The selector is what makes rotation safe#
Every DKIM-Signature header carries an s= tag naming a selector and a d= tag naming a domain. A verifier combines them into one DNS name, <selector>._domainkey.<domain>, and fetches the key from there. The message tells the verifier which key to use.
That indirection is the entire reason rotation can be non-disruptive. A domain can publish as many selectors as it likes at once, and each message points at exactly one of them. A message signed last Tuesday under 202608 keeps verifying for as long as 202608 is published, whatever you do to any other selector. The two keys are not competing for one slot; they live at different names.
This is also why replacing a key in place is the move to avoid. Overwriting the p= value at an existing selector breaks every message already in flight that names it: the name still resolves, and the key behind it no longer matches the signature. The lookup succeeds and the cryptography fails. If any of that is unfamiliar, our introduction to DKIM covers the signature format and what receivers do with it.
The overlap procedure#
Six steps, in this order:
- Generate the new key pair and pick a new selector name. Date-based names such as
202609or2026q3sort sensibly and tell you at a glance how old a key is. - Publish the new public key at the new selector. Change nothing about signing yet. Your domain now has two keys published, one of them unused.
- Confirm the new record resolves before anything signs with it. A key that is not yet visible to a verifier produces a permanent failure for every message naming it.
- Switch the signer to the new selector. New mail now carries
s=pointing at the new name. - Leave the old selector alone. This is the wait, and it is the step people compress.
- Retire the old key once nothing signed with it can still be in transit.
One ordering trap: publish the new record before you go looking for it. A resolver asked for a name that does not exist yet can hold on to that answer for a while, so a premature test leaves you waiting on a cached negative rather than on DNS propagation.
How long to leave the old key published#
Long enough that no message signed with the old key is still undelivered somewhere.
Mail that cannot be delivered on the first attempt does not bounce straight away. It sits in a queue and is retried, and those queue lifetimes are measured in days rather than minutes. A message your server accepted on Monday can still be attempting delivery later in the week, and the verifier at the far end looks up the old selector at the moment it finally receives that message, not at the moment you sent it.
Large senders enforce this. Amazon SES will not normally let you change the DKIM signing key length for an identity more than once in a 24-hour period, and its documentation gives the reason plainly: while email is in transit DNS is being used to authenticate it, so flipping keys too quickly can invalidate a key that in-flight mail still depends on.
A week of overlap is comfortable for most senders and costs one extra TXT record. There is no real penalty for longer, with one exception pulling hard the other way: a published old key is a usable old key. If you are rotating because you think the private key was stolen, the calculation inverts. Revoke now and accept that some in-flight mail fails DKIM, because the alternative leaves a forger's key authorised for another week.
Revoking versus deleting#
There are two ways to take a selector out of service: delete the TXT record, or keep it and empty its p= value. RFC 6376 defines an empty p= as a revoked key.
For the receiving verifier the two are close to equivalent. A key record that does not exist and one whose p= is empty both end in a permanent failure for that signature. The practical difference is what you can see afterwards. A revoked record still resolves, so a lookup tells you the selector existed and was deliberately retired. A deleted one is indistinguishable from a selector that never existed, or one somebody removed by accident. Our DKIM record lookup reports an emptied key in those terms, saying the key has been intentionally revoked and the selector is disabled, rather than calling it missing or broken.
A third outcome is worth knowing: a lookup that fails for a temporary reason, such as an unreachable zone, is a temporary failure rather than a permanent one, and receivers may defer instead of rejecting. That distinction stays quiet until the day your DNS provider has an incident.
The 255-character problem#
A TXT record is not one string. RFC 1035 defines TXT data as one or more character-strings, and a character-string is a length octet followed by at most 255 octets of text. Any single piece of text in a TXT record therefore stops at 255 characters, and a longer value is published as several strings that the reader concatenates.
DKIM hits that ceiling at exactly the moment most people rotate. A 1024-bit RSA public key, encoded the way DKIM publishes it, is 216 characters of base64. The 2048-bit equivalent is 392. The upgrade everyone eventually makes is the upgrade that pushes the value past what one string can hold, before the v=DKIM1; k=rsa; p= prefix is even added.
Most DNS providers split it for you. Some editors truncate silently at 255 instead. The failure is quiet: the record resolves, the key is malformed, signatures fail with no obvious cause. Our lookup rejoins the quoted segments before parsing, so a correctly split key reads as one key, while a truncated one usually surfaces as a public key whose length the tool cannot work out at all.
Ed25519 sidesteps this. Defined for DKIM in RFC 8463, it uses k=ed25519 in the record and a=ed25519-sha256 in the signature, and its public key is 256 bits: 32 bytes, 44 characters of base64, comfortably inside one string. Verifier support is not universal, which is why the RFC notes that signers can attach multiple signatures using old and new algorithms. One message can carry an RSA signature and an Ed25519 signature at once, each naming its own selector. That is a dual publish rather than a rotation, and both keys stay live.
Verifying each step#
Each step should be confirmed before the next one starts. Four checks cover it.
- After publishing, query the new selector by name. Our DKIM tool takes an optional selector, so you can ask for precisely the name you just created. Left empty it probes 57 common selector names in parallel, which is how you find what a domain publishes when you do not already know. During your own rotation you do know.
- Read what it says about the key. RSA at 2048 bits or more is badged strong, 1024 to 2047 is badged weak with an upgrade prompt, and anything shorter is badged broken. Ed25519 keys are reported at 256 bits.
- After switching the signer, send yourself a message and read the
s=value in itsDKIM-Signatureheader. That is the only evidence the signer actually changed rather than merely being configured to. Our guide to reading email headers shows where to find it. - After revoking, look the old selector up once more and confirm it reports as revoked rather than missing.
One trap while testing. A key record can carry t=y, marking the domain as testing DKIM, and verifiers are told not to treat a message from a signer in testing mode any differently from unsigned mail even when the signature fails. That makes a test which cannot fail, and therefore proves very little. Take it off before you rely on the key.
What rotation does not fix#
Rotation limits how long a stolen key stays useful. It does nothing about a message that was legitimately signed and then replayed: the signature stays valid on that exact message for as long as its key is published, so anyone who captures one can send it again. The signature's own x= tag carries an expiration timestamp for the signature itself, a separate control from the key's lifetime.
Rotation also does not change your policy. DKIM only establishes that a message was signed by a key at a domain; what a receiver should do when that fails is a DMARC question. The three mechanisms are easy to conflate, and we untangle them in SPF, DKIM, and DMARC explained.
The rotation itself is two DNS edits and one configuration change. The part that needs care is the gap between them.
Look up a DKIM selector
Check a specific selector by name, or let it probe the common ones for a domain. You get the key type and estimated length, revocation and testing-mode flags, and a warning for anything the record gets wrong.
Open the DKIM lookup →