PRACTICAL GUIDE

Rotate DKIM keys without losing the old selector too soon

By ApiVect ·

Publish the new DKIM selector ahead of the switch, account for cached DNS answers and verify a test message before retiring the old key.

Rotate DKIM keys without losing the old selector too soon

A planned DKIM key change affects two systems. Your mail service starts signing with a new private key, and recipients need the corresponding public key in DNS. Plan those steps separately. Publish the new selector before sending with it, and keep the old public key available while messages signed with it may still be awaiting verification.

1. Map the senders that use the old selector

Pick a test message from each sending service you control, such as a billing system, a support desk or a transactional mail provider. In each relevant DKIM-Signature, record the signing domain in d= and the selector in s=. The visible From domain may differ from the signing domain. If two services share a selector, verify both before scheduling its removal. Note who manages each key and whether your provider asks you to publish a TXT record or a CNAME.

2. Publish the new selector before switching the signer

In this fictional example, example.org uses billing-old today and plans to use billing-next. The new DNS name is billing-next._domainkey.example.org. Publish the record supplied by your mail provider at that name and leave billing-old._domainkey.example.org in place. A fresh selector allows recipients to look up the right key for each message during the transition.

Check the published record with the authoritative DNS provider, then test through recursive resolvers relevant to your mail flow. A resolver that asked for the new name too early may still return a cached negative answer even after the authoritative server has the record. The DNS specification derives the negative cache TTL from the smaller of the SOA record's TTL and its MINIMUM field in the authoritative negative response. Lowering the TTL on the new key does not clear an absence that was already cached. Recheck after the observed remaining negative TTL and verify that any delegated CNAME also resolves to the intended key.

Keep these observations distinct in your change log. A name error, an existing name with no record of the requested type and a resolver failure each warrant different follow-up. A failure such as SERVFAIL gives you no reliable answer about whether the key exists. Record the queried name, record type, resolver, result and UTC time so another operator can reproduce the check.

3. Confirm that real messages use the new key

Once the new selector resolves as expected, switch signing for a controlled sender and send a fresh message to a mailbox you control. Confirm the actual signature uses the expected d= and s=. Then use the receiving service's trusted authentication results to confirm that it verified that signature. Where there are several signatures, make sure the passing result is for the signing domain and selector you changed. A DNS lookup can confirm publication. The receiver's result tells you whether verification worked for that message.

4. Retire the old key after the overlap

Use the mail provider's instructions, remaining queues and your own test results to decide when to remove the old public key. Confirm that every sender using it has moved. Keep the old record through the window in which previously signed messages may still need verification. Record the cutover and retirement separately, and assign someone to confirm the final DNS state. If you suspect a compromised key, follow your provider's incident and revocation procedure. The planned overlap above assumes both keys remain under your control.

Use ApiVect to review the DNS side

Our commercial Domain & Email Security API can inspect public DKIM records for selectors you supply. For the fictional example, the request body below checks both names for one signing domain. Repeat the check for each distinct signing domain you operate, and keep the receiver's message authentication results alongside the DNS evidence.

{
  "domain": "example.org",
  "dkimSelectors": ["billing-old", "billing-next"]
}

Sources and further reading

← More news and guides · Browse the guide library