What "rotating a DKIM key" actually means
DKIM works with a pair of keys. Your mail platform holds the private key and uses it to stamp a signature onto every message it sends. You publish the matching public key in DNS, and receiving mail servers look it up to confirm the signature is real and that the message wasn't tampered with along the way.
The public key lives at a DNS name built from something called a selector:
<selector>._domainkey.example.com
So if your selector is s1 and your domain is example.com, receivers go looking for s1._domainkey.example.com. The selector is just a label. Its only job is to tell the receiver which key to fetch, which means you can have several keys published side by side without them stepping on each other.
Rotating a key means retiring an old key pair and putting a new one into service. You generate a fresh pair, publish the new public key under a new selector, switch your mail platform over to signing with the new private key, and eventually retire the old public key.
Why rotate the DKIM key?
Two reasons, and the second one matters more than people expect.
The obvious one: keys get stolen or cracked. A private key sitting on a mail server for three years is a much bigger prize than one that gets replaced twice a year. If somebody does walk off with it, they can sign mail as you until you notice. Rotating on a schedule caps how long a stolen key stays useful.
The one people miss: rotation is a fire drill. M3AAWG makes this point repeatedly in their key rotation guidance, and it holds up in practice. The first time you rotate a key it will be awkward; you'll discover the DNS team is a different team, that nobody knows who owns the Klaviyo account, or that one vendor requires a support ticket. If you only do it during an actual emergency, you'll be figuring all that out under pressure. Do it routinely and it becomes boring, which is exactly what you want.
The baseline to aim for
Straight from the M3AAWG best common practices document (March 2019 revision):
Item | Recommendation |
Rotation frequency | At least every six months |
Key length | 1024-bit RSA minimum; 2048-bit preferred. 512-bit is deprecated outright (RFC 8301) |
Overlap window | Keep the old public key published for 7 to 30 days after you stop signing with it |
Retiring a key | Set the record's p= field to empty rather than deleting the record |
Selector names | Never reuse one |
Audit | Check about a week after each rotation that it actually happened |
Two of those deserve a note.
The overlap window exists because mail already in flight, and mail sitting in a mailbox that a filter re-checks later, still needs the old public key to validate. Pull it too early and you'll fail signatures on messages you already sent.
Emptying p= instead of deleting the record is a small thing that saves confusion later. A record with v=DKIM1; p= says "this key was intentionally retired." A missing record says "something might be broken." Leave the tombstone.
Never reuse selector names. If you republish s1 with a different key, old mail signed with the original s1 key will now fail validation, and any receiver caching the old value gets an inconsistent answer. Pick a naming scheme that makes reuse impossible — including a date is the easy way, e.g. mktg-202607-2048. That tells you the stream, the month it went live, and the key size, which is genuinely useful at 2 a.m.
Note on blank keys: Much of the guidance above on retiring a key by emptying its p= field, keeping a spare key pre-published for emergencies, assumes you're managing DKIM records directly in your own DNS. If you're pointing DKIM to Valimail, you don't need to do this. Publishing a new key is a button in the Valimail Enforce platform rather than a DNS change request, so there's no propagation delay to pre-empt, and the report already tracks last-seen activity per key, so you can tell what's in use without leaving placeholders behind to mark your own history.
How rotation works: TXT records vs. CNAME records
This is the fork in the road that determines how much work rotation is for you. Almost every platform you deal with will use one of these two models.
1. With the TXT model, you hold the reins
You publish the public key directly in your own DNS as a TXT record:
s1._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."
The whole key sits in your zone. Nobody can change it but you. That's the upside and the downside, nothing rotates unless you rotate it.
How a rotation goes:
Generate a new key pair, or have the vendor generate one and hand you the public half.
Publish the new public key under a new selector, e.g. s2._domainkey.example.com. The old s1 record stays exactly where it is.
Wait for DNS propagation. Don't skip this. Verify with
dig TXT s2._domainkey.example.comfrom a few different resolvers.Switch the mail platform over to signing with the new private key.
Leave s1 in place for 7 to 30 days.
After the window, edit s1 down to
v=DKIM1; p=and leave it there.
A useful habit worth stealing from the M3AAWG document: keep one key pre-published and unused at all times. If you're signing with s2, have s3 already sitting in DNS doing nothing. If s2 gets compromised, the emergency response is a single config change on the mail server rather than a DNS change, a propagation wait, plus a config change. It costs you nothing to leave it there.
2. The CNAME model, where the vendor holds the reins
Instead of the key itself, you publish a pointer to a record the vendor controls:
s1._domainkey.example.com. CNAME s1.domainkey.u123456.wl.sendgrid.net.
The actual TXT record with the key lives on the vendor's DNS. When they want to rotate, they change their end. Your DNS never changes, and you don't have to be involved at all.
How a rotation goes: usually it doesn't involve you. The vendor generates the new key, publishes it behind their end of the CNAME, and switches signing over. You may not even get a notification.
This is why most of the big ESPs moved to CNAME delegation, as it lets them rotate on their own schedule without filing a DNS change request with every customer.
Two things to watch for:
The CNAMEs must never break. If somebody prunes "unused" DNS records during a cleanup, or a zone gets rebuilt from a stale export, the vendor's rotation stops working and DKIM starts failing. Make sure these records are documented as load-bearing.
You've handed over some control. Any rotation is on their calendar, not yours. If your security policy demands a rotation on a specific date, or you need to force one after an incident, you're filing a support ticket. Worth knowing before you need it.
Side by side
| TXT | CNAME |
Where the key lives | Your DNS | Vendor's DNS |
Who rotates it | You | The vendor |
Effort per rotation | Real work: new record, propagation wait, platform switch, cleanup | Usually none |
Who can force a rotation | You, any time | Vendor, or you via support request |
Main failure mode | Nobody ever gets around to it | Someone deletes the CNAME records |
Typical record count | 1 per active key | 2-4, pre-provisioned for rotation |
One note on the record count: when you see a platform asking for three or four CNAMEs, that's the rotation mechanism, not redundancy. Amazon SES is the clearest example; it runs an active key (signing now), a passive key (still published so older mail validates), and a pending key (staged for next time). During a rotation, records shuffle roles rather than getting created and destroyed. Same pattern as the pre-published spare key in the TXT model, just automated.
Service-by-service reference
Below are the 22 sending services in our current inventory, split by who's responsible for the rotation. Check which model your account is actually on before acting; several of these platforms offer both, and older accounts are often still on the manual path.
Table A: Vendor rotates for you
Nothing to do on a schedule. Your job is to keep the records intact and verify they still resolve.
Service | DNS records | Rotation | What you need to do |
Amazon SES (Easy DKIM) | 3 CNAME | Automatic, every 90 days | Nothing. The three records are active / passive / pending and rotate through those roles on their own. Don't delete any of them. |
Ascend by Wix | 4 CNAME | Automatic | Nothing. Runs SendGrid and SparkPost underneath, two CNAMEs each. Wix uses SendGrid's default |
Braze (SendGrid path) | 2 CNAME | Automatic | Nothing. Also uses the default Sendgrid selectors |
Brevo | 2 CNAME | Automatic | Nothing for the CNAME setup. Older accounts may still have a legacy Sendinblue TXT record — see Table B if so. |
HubSpot | 2 CNAME | Automatic | Nothing. |
Iterable (Amazon SES path) | 3 CNAME | Automatic | Nothing. Same active/passive/pending pattern as SES direct. Accounts on the Mailgun or SparkPost path are in Table B. |
Klaviyo | 2 CNAME | Automatic | Nothing. |
MailChimp | 2 CNAME | Automatic | Nothing. |
Mailgun by Sinch (Automatic Sender Security) | 2 CNAME | Automatic | Nothing. You can also trigger a rotation yourself from the dashboard if you need one. See Mailgun's rotation article. |
Sailthru | 2 CNAME | Automatic | Nothing. |
Salesforce | 2 CNAME | Automatic, every 30 days | Nothing routine, but: DKIM is configured per Salesforce instance, and an instance refresh wipes it. Add "reconfigure DKIM" to your post-refresh checklist. |
Salesforce Marketing Cloud | 2 CNAME | Automatic | Nothing. |
SendGrid (Automated Security) | 2 CNAME | Automatic | Nothing. |
Table B: You own the rotation
These Services publish the key in your DNS as a TXT record and will not rotate on their own. Every one of these needs a calendar entry.
Service | DNS records | Rotation | What you need to do |
Adobe Campaign | 1 TXT | Manual | Full manual rotation: generate a new pair, publish under a new selector, switch signing in Campaign, and retire the old record after 7–30 days. |
Amazon SES (BYODKIM) | 1 TXT | Manual | You supplied the key, so you rotate it. Consider moving to Easy DKIM if you don't specifically need to own the key material. |
Braze (SparkPost path) | 1 TXT | Manual | Full manual rotation. Coordinate with whoever owns the Braze account. |
Brevo (legacy Sendinblue) | 1 TXT | Manual | Full manual rotation, or migrate the account to the current CNAME setup and stop worrying about it. |
Cuenote | 1 TXT | Manual | Full manual rotation. |
Epsilon | 1 TXT | Manual | Full manual rotation. Epsilon is typically a managed relationship, so expect this to go through your account contact. |
Google Workspace | 1 TXT | Manual | Generate a new key in the Admin console, publish the new TXT record, wait for propagation, then start authenticating with it. |
Infobip Email | 1 TXT | Manual | Full manual rotation. |
Iterable (Mailgun or SparkPost path) | 1 TXT | Manual | Full manual rotation. Confirm which backend your account uses before you start. |
KnowBe4 | 2 TXT (one for training mail, one for phishing simulations) | Manual | Two separate rotations. Don't rotate one and forget the other. The phishing simulation stream is easy to overlook because it isn't "real" mail. |
Mailgun by Sinch (legacy config) | 1 TXT | Manual | Full manual rotation, or migrate to Automatic Sender Security and let Mailgun handle it going forward. |
SendGrid (Manual Security) | 1 TXT | Manual | Full manual rotation, or switch the account to Automated Security. |
SparkPost | 1 TXT | Manual | Full manual rotation. |
Table C: Special cases
Service | Records | Rotation | Notes |
Microsoft 365 | 2 CNAME | On request | Microsoft does not rotate on a schedule. The two CNAMEs are there so you can trigger a rotation, either through the Defender portal or with PowerShell (instructions). Treat this as a manual task on your calendar, even though it uses CNAMEs. |
DigitalOcean | N/A | N/A | Not a sending service. It's a hosting platform. Mail from DigitalOcean IPs comes from MTAs running inside droplets hosted in DigitalOcean. Whatever DKIM setup exists belongs to whoever configured that MTA, so track it as its own mail stream. |
The short version
Table A: 13 services rotate themselves. Verify the records resolve; otherwise, leave them alone.
Table B: 13 configurations across 12 services need manual rotation on your schedule. (Several platforms appear in both tables because the answer depends on which setup your account is using)
Microsoft 365 looks automatic, but it isn't. It's the one most likely to be missed.
Legacy accounts are where the surprises live. Braze, Brevo, Iterable, Mailgun, SendGrid, and Amazon SES all have a modern automatic path and an older manual one. Don't assume from the vendor name, go look at the account.
Before you rotate anything: build the inventory
You cannot rotate what you don't know about. This is the step people skip and then regret.
List every mail stream leaving your domains. Transactional mail, marketing campaigns, employee mail, the phishing simulation platform, the ticketing system, the CI server that emails build failures. Anything that signs as you.
Building the inventory with the DKIM Continuous Protection Report
If you're a Valimail customer on Enforce Enterprise, most of the inventory above already exists. The DKIM Continuous Protection Report is effectively the table you were about to build by hand. (It's an Enforce Enterprise feature; if you don't see it, reach out to your Account Manager)
The report lists every DKIM record Valimail knows about for your domains, with one row per key:
Column | How to use it for the inventory |
Domain / subdomain | Where the record is published. Fills in your domain list, including subdomains you may have forgotten. |
Sender | The service the key belongs to. This is your mail stream list. |
DKIM Selector | Current selector names per stream. |
Bits | Key size. Anything under 2048 bits gets flagged for you. |
Usage | The first and last date when the key was last seen signing emails. |
Rotation | Recommendation for key rotation. |
Details | Metadata like Domain Owner, Sender Owner, or Notes. |
Actions | Add or Edit details for each key, and an option to delete inactive keys. |
How to work through it:
Download the CSV. That's your starting inventory document rather than a blank spreadsheet.
Sort by Type. Everything marked Manual is work you own; cross-reference against Table B. Everything marked CNAME is mostly Table A, with Microsoft 365 as the exception to watch.
Sort by Last Seen date. Keys that haven't been seen in one to three months are probably dead, a decommissioned vendor, a campaign platform nobody renewed. Confirm the stream is genuinely retired, then delete the key. This is the fastest way to find out which services are actually still in use, and it shrinks the list of things you have to rotate.
Sort by Uploaded date to find the oldest keys and start there. Anything over two years old drags down your DKIM health score and is the obvious first rotation.
Fill in the ownership fields. You can edit Associated Service, Domain Owner, Sender Owner, and a free-text Comment directly on each key. Do this once and the report becomes the answer to "who do I talk to about this stream" instead of a question you re-answer every six months. The Comment field is a good place to note how a change gets requested at that vendor.
Use the Create DKIM Key button when you publish a new record, so the report stays accurate as you rotate.
⚠️ Caution: Don't delete a CNAME key just because it has no Last Seen date. Automatic rotation relies on a set of records where only one is signing at a time, and the others are the passive and pending keys waiting their turn, so they legitimately show no activity. Deleting one breaks the vendor's next rotation. Only remove CNAME keys once you've confirmed the sending service itself is retired, and then remove the whole set together.
A workable schedule
If you're starting from nothing, this is a reasonable target:
Manual TXT services: rotate every six months. Pick two months and stick to them. Avoid your business's peak season; April and October work well for most retail-adjacent operations, since they dodge both the holiday run-up and the post-holiday cleanup.
Microsoft 365: same cadence, triggered manually.
CNAME-managed services: no rotation task. Verify records resolve during your regular DNS review.
Salesforce: no rotation task, but reconfigure DKIM after any instance refresh.
Audit: one week after each rotation window.
Full inventory review: annually, plus after any merger, acquisition, or new vendor onboarding.
If six months feels like too much for your first pass, do it once and see how long it actually takes. It's usually less than people fear, and the second time is much faster than the first.
References
M3AAWG DKIM Key Rotation Best Common Practices, revised March 2019: https://www.m3aawg.org/DKIMKeyRotation
RFC 6376: DomainKeys Identified Mail (DKIM) Signatures
RFC 8301: Cryptographic Algorithm and Key Usage Update to DKIM (deprecates 512-bit keys)
Mailgun key rotation: https://help.mailgun.com/hc/en-us/articles/16956951504539-How-can-I-rotate-my-DKIM-key
Microsoft 365 DKIM rotation: https://learn.microsoft.com/en-us/defender-office-365/email-authentication-dkim-configure#rotate-dkim-keys
SendGrid DKIM records: https://www.twilio.com/docs/sendgrid/ui/account-and-settings/dkim-records
