DKIM signing was switched on for the company domain years ago, the two CNAME records went into DNS, and the DKIM status has read Valid ever since. Nobody has gone back to rotate DKIM keys Microsoft 365 generated on that day, and there is a fair chance both keys are still the 1024-bit default.

Neither is an outage, but both are questions an auditor or an insurance form will eventually ask. The rotation is one cmdlet. It runs on a clock you do not control, the key-size change lands on one selector at a time, and it does nothing for the other systems that sign mail as your domain.

How the two selectors actually work

When you enable DKIM for a custom domain, Microsoft generates two public-private key pairs. The private keys are inaccessible to you. What you publish is two CNAME records, selector1._domainkey and selector2._domainkey, pointing at the public keys Microsoft hosts. Microsoft is explicit that only one selector is active and used; the other is activated only after a future key rotation, once the original selector is deactivated.

So a rotation is a swap: the signing selector becomes the spare, the spare gets a fresh key and signs, and the next rotation swaps back. Receivers find the key from the s= value in the DKIM-Signature header, which names the selector; d= names the signing domain.

One detail matters for planning. RFC 6376 says signers are ill-advised to reuse selectors for new keys, because reuse makes it impossible to tell a message that failed because the key is no longer valid from one that is forged. M3AAWG strongly discourages reusing selector names, noting that old messages will fail re-validation against the new key. Microsoft's two fixed names are reused on every second rotation by design. You cannot change that, but it is why the spacing between rotations matters.

What do I have right now?

Connect to Exchange Online PowerShell and run the property list Microsoft gives for this job:

Get-DkimSigningConfig | Format-List Name,Enabled,Status,Selector1CNAME,Selector1KeySize,Selector2CNAME,Selector2KeySize,KeyCreationTime,RotateOnDate,SelectorBeforeRotateOnDate,SelectorAfterRotateOnDate

The fields that matter:

  • Selector1KeySize and Selector2KeySize: the bit size of each key. The KeySize parameter on New-DkimSigningConfig accepts 1024 or 2048 and lists 1024 as the default, so a domain set up without that parameter is likely to show 1024 on both.
  • KeyCreationTime: the UTC date and time the key pair was created.
  • RotateOnDate: the date and time of the previous or next rotation.
  • SelectorBeforeRotateOnDate and SelectorAfterRotateOnDate: which selector signs before and after that date. They are always different values, selector1 or selector2.

Microsoft allows a rotation only when the domain's toggle is Enabled and its status is Valid or CnameMissing.

Running the rotation, and moving to 2048 bits

In PowerShell the command is Rotate-DkimSigningConfig -Identity yourdomain.com -KeySize 2048. Leave out -KeySize and the new key keeps the current bit depth. Then re-run the property list and confirm KeyCreationTime, RotateOnDate and the two selector fields changed.

In the portal, go to the Defender portal at security.microsoft.com, then Email & collaboration > Policies & rules > Threat policies > Email authentication settings, open the DKIM tab, click the domain's row to open its details flyout, and select Rotate DKIM keys at the bottom. The flyout status changes to Rotating keys for this domain and signing DKIM signatures., the Publish CNAMES values go blank for both selectors, and the rotate button is grayed out. The blank CNAME values are expected during a rotation; they are not an instruction to delete anything. Microsoft documents the key-size choice only through the PowerShell KeySize parameter, so use PowerShell for this job.

Now the part that catches people. Microsoft states that when you change the bit depth from 1024 to 2048, the update applies only to the next active selector during the first rotation. The previously inactive selector only becomes active, and only moves to 2048, when you rotate again. One rotation leaves you with one 2048-bit key signing and one 1024-bit key sitting as the spare. Getting both selectors to 2048 takes two rotations.

Why bother with 2048 at all: RFC 8301, which updates the DKIM standard, says signers MUST use RSA keys of at least 1024 bits and SHOULD use keys of at least 2048 bits. It also requires verifiers to handle keys from 1024 to 4096 bits, and notes that verifier policies can use key length as one metric for whether a signature is acceptable. The 1024-bit default is the floor, not the recommendation.

How long does it take, and how long should the old key stay?

Microsoft's answer on the first half is specific: it takes four days (96 hours) for the new private key to start signing, and until then the existing key keeps signing. The changeover happens at the RotateOnDate value. While a rotation is in progress you cannot start another one.

The second half is where stray numbers creep in. Microsoft's DKIM page mentions 48 hours only for DNS propagation of new CNAME records and for a status stuck on CnameMissing. Neither is a key overlap window, and the page does not say how long the outgoing key stays published after the new one takes over. Because the CNAMEs point at records Microsoft hosts, that retention is not yours to manage.

The standards bodies do address it. RFC 6376 advises that when rotating, signing should start immediately with the new key and the old public key should be retained for a reasonable validation interval before removal, because verifiers can defer validation, perhaps until the message is actually read. M3AAWG is more concrete: keep the old public key unchanged in DNS for a minimum of seven days and up to 30 days, then retire it by publishing an empty p= value rather than deleting the selector record. M3AAWG also recommends rotating at least every six months.

You cannot set the retention in Microsoft 365, but you can control the spacing. The second rotation is the one that puts a new key on the selector that signed your older mail, so wait at least M3AAWG's seven-day minimum after the first RotateOnDate before starting it. That margin is a rule of thumb drawn from M3AAWG, not a Microsoft requirement.

Why are some of my signatures not from Microsoft at all?

A Microsoft 365 rotation changes the keys behind selector1 and selector2 and nothing else. Any other service signing as your domain has its own selector, key and rotation process. Microsoft's own example is a bulk mailer whose messages carry s=s1024; d=marketing.contoso.com: the service gives the customer a public key, the customer publishes it under the marketing subdomain, and the service signs with the matching private key. Rotating that key means going through that service, on its terms.

Some services sign with their own domain in d= instead, which can verify and still do nothing for DMARC. RFC 9989, which obsoletes RFC 7489, requires the DKIM signing domain to be aligned with the From domain for DKIM to count. Relaxed alignment means the two share an Organizational Domain; strict means they are identical; the adkim tag in your DMARC record picks the mode and defaults to relaxed. RFC 9989's own table marks a signing domain with no shared Organizational Domain as no alignment. A message can carry several signatures, and DMARC passes on DKIM if any one of them aligns.

To build the inventory, use two instruments:

  • DMARC aggregate reports. RFC 9990 defines the report format, and each DKIM result in a report carries the domain (the d= tag) and the selector (the s= tag); RFC 9990 makes the selector required. M3AAWG names a p=none DMARC policy with an aggregate reporting address as a useful tool for identifying your mail streams before rotating.
  • Message headers. Send a message from each system to an outside mailbox and read the DKIM-Signature and Authentication-Results headers for d=, s= and dkim=pass.

Any selector in that inventory that is not selector1 or selector2 belongs to someone else's rotation schedule.

A worked example: a 30-seat firm

A 30-seat engineering firm runs mail on Microsoft 365 for one custom domain and sends a monthly newsletter through a marketing platform. The insurer's renewal form asks when DKIM keys were last rotated.

On day 0, the administrator runs the property list. Both Selector1KeySize and Selector2KeySize read 1024, KeyCreationTime is from the year the domain was added, and SelectorBeforeRotateOnDate is selector1. The administrator runs Rotate-DkimSigningConfig with -KeySize 2048 and re-runs the list: RotateOnDate is now four days out, and SelectorAfterRotateOnDate is selector2.

On day 4, after the RotateOnDate passes, the administrator sends a test from a staff mailbox to an outside address. The header shows s= naming selector2 and dkim=pass.

On day 11, a week after the first changeover, the administrator runs the same rotation command again, with -KeySize 2048 again so there is no ambiguity. Four days later selector1 is signing, and the property list shows 2048 for both selectors. Meanwhile the aggregate reports for those two weeks show the newsletter signed with the platform's own domain in d=, which does not align with the firm's From domain. That stream needs its own fix in the platform's domain settings, and none of the Microsoft work touched it. The next rotation goes on the calendar six months out.

Where this goes wrong

  • Only one CNAME was ever created. Microsoft lists a missing selector2 record as a common mistake: signing can enable, but without it you cannot rotate DKIM keys. Microsoft says to always create both records, even though only one is active at a time.
  • A TXT record where the CNAME should be. Microsoft does not support publishing the public key directly as TXT; the CNAME is what delegates key management to Microsoft.
  • A proxied CNAME. If the DNS host is Cloudflare, Microsoft says the proxy must be off for the DKIM CNAMEs or DKIM verification fails.
  • Assuming the initial domain is covered. Microsoft states that there is currently no automatic DKIM key rotation for the *.onmicrosoft.com domain.
  • Rotating twice in a row. A second rotation started on day 1 is blocked while the first is in progress. Stopping after one leaves the spare at 1024.
  • Testing internally. Same-domain mail carries no DKIM signature, and Microsoft also advises against testing via AOL, which might skip the DKIM check if SPF passes.

The decision rule

If either selector reports 1024, schedule two rotations with -KeySize 2048, at least a week apart after the first changeover, and verify each with an outside test message. If both already report 2048, rotate on a fixed six-month cycle. Either way, before you call the domain done, pull the selectors out of your aggregate reports: every one that is not selector1 or selector2 is a separate key, owned by a separate vendor, that this procedure never touched.