The DKIM status CnameMissing means Microsoft 365 has created DKIM keys for your custom domain but can't find the two CNAME records, selector1._domainkey and selector2._domainkey, that point to those keys. To fix it, copy the exact Selector1CNAME and Selector2CNAME values from Get-DkimSigningConfig (or the domain's flyout on the DKIM tab in the Defender portal), publish them in your domain's public DNS with only selector1._domainkey and selector2._domainkey as the host names, and enable signing again once they resolve. When the status changes to Valid, outbound mail from that domain carries a DKIM signature with d= set to your domain.
Who this is for and what you will have
This guide is for Microsoft 365 administrators who tried to turn on DKIM for a custom domain and got a client error, a CnameMissing status that never clears, or a PowerShell error saying the CNAME record doesn't exist. It also helps after a migration, when a domain has moved into a new tenant and the old DKIM records no longer match. At the end you will have:
- The correct CNAME values for every domain that sends mail from Microsoft 365.
- Records published in public DNS and checked from outside your network.
- DKIM signing enabled, with the status
Valid, and a test message showingdkim=passfor your domain.
How DKIM signing works in Microsoft 365
When you configure DKIM for a custom domain, Microsoft 365 generates two public-private key pairs. The private keys stay in Microsoft 365 and are never exposed. The public keys are published by Microsoft, and you point to them from your own zone with two CNAME records, called selectors. Only one selector is active at a time; the other is used after a future key rotation.
Without your own configuration, outbound mail from a custom domain isn't signed by that domain. Messages from the initial *.onmicrosoft.com domain are signed automatically. For DMARC, a DKIM pass only counts when the signing domain (d=) aligns with the From address domain, which is why signing with the custom domain matters.
The CNAME target format depends on when the domain was added:
Domains added since May 2025 (new format):
selector1._domainkey -> selector1-contoso-com._domainkey.contoso.n-v1.dkim.mail.microsoft
selector2._domainkey -> selector2-contoso-com._domainkey.contoso.n-v1.dkim.mail.microsoft
Existing custom domains and initial domains (old format):
selector1._domainkey -> selector1-contoso-com._domainkey.contoso.onmicrosoft.com
selector2._domainkey -> selector2-contoso-com._domainkey.contoso.onmicrosoft.comIn the new format, contoso-com is your domain with dashes instead of periods, contoso is the prefix of your initial *.onmicrosoft.com domain, and the single character before -v1 (here n) is a dynamic partition character that Microsoft assigns and you can't predict. The old and new formats can't coexist for the same selector. The values above are illustrations only; this is the single most common cause of CnameMissing: records copied from an old article or another tenant instead of from your own configuration.
The status values you will see
| Status | Meaning | What to do |
|---|---|---|
NoDKIMKeys | No keys exist yet for the domain | Create keys (portal toggle or New-DkimSigningConfig) |
CnameMissing | Keys exist; the CNAME records aren't detected | Publish or correct the two CNAME records |
Valid | Records detected | Signing is active if Enabled is True |
In the portal, a domain that is signing shows Signing DKIM signatures for this domain in its details flyout.
Prerequisites
- The custom domain is added and verified in Microsoft 365. Run
Get-AcceptedDomainto confirm it is available. - Access to the DNS hosting provider for the domain (not just the registrar, if the zone is hosted elsewhere).
- Exchange Online PowerShell, or access to the Defender portal at
https://security.microsoft.com. To see which roles can run the DKIM cmdlets in your organization, useGet-ManagementRole -Cmdlet Set-DkimSigningConfigas described in Microsoft's article on finding the permissions for any Exchange cmdlet. - A mailbox outside your organization, such as an Outlook.com or Gmail address, for testing.
Step 1: Get the exact CNAME values
Connect to Exchange Online PowerShell and list the DKIM configuration of every domain:
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
Get-DkimSigningConfig | Format-List Name,Enabled,Status,Selector1CNAME,Selector2CNAMEIf the domain is listed with Enabled : False and Status : NoDKIMKeys or CnameMissing, copy Selector1CNAME and Selector2CNAME.
If the domain isn't listed at all, create its configuration with signing disabled, then run the previous command again:
New-DkimSigningConfig -DomainName contoso.com -Enabled $false -KeySize 2048KeySize accepts 1024 or 2048, and 1024 is the default if you leave it out. After this command the domain shows Status : CnameMissing, which at this point is expected.
In the Defender portal the equivalent is Email & collaboration > Policies & rules > Threat policies > Email authentication settings > DKIM tab (or https://security.microsoft.com/authentication?viewid=DKIM). Sliding the toggle for a domain with NoDKIMKeys produces a Client error dialog that contains the values; select OK, then open the domain's details flyout, where the Publish CNAMEs section shows the same values in a cleaner form with a Copy option.
Step 2: Publish the two CNAME records
At your DNS host, create two records in the domain's zone:
| Type | Host name | Points to | TTL |
|---|---|---|---|
| CNAME | selector1._domainkey | Your Selector1CNAME value | 3600 |
| CNAME | selector2._domainkey | Your Selector2CNAME value | 3600 |
Points to watch while you type:
- Host name only. Many DNS hosting portals append the zone name automatically. If you enter
selector1._domainkey.contoso.comin such a portal, the record is created asselector1._domainkey.contoso.com.contoso.com. Enterselector1._domainkeyand check how the portal displays the saved record. - Character for character. The values mix dashes, periods and underscores. Microsoft's own guidance calls out typos here as easy to make; paste rather than retype.
- CNAME, not TXT. Microsoft 365 uses CNAME records for DKIM. Don't paste a public key into a TXT record.
- Public DNS. If you run split DNS, the records must be in the zone the internet sees, not only on internal DNS servers.
- Subdomains. Each subdomain that sends mail needs its own DKIM configuration. For
marketing.contoso.com, the records areselector1._domainkey.marketing.contoso.comandselector2._domainkey.marketing.contoso.com, with the valuesGet-DkimSigningConfigshows for that subdomain. - Every sending domain. With two custom domains you need four records: two in each domain.
Step 3: Check the records from outside your network
Before you go back to Microsoft 365, confirm that a public resolver returns the records. Querying a public resolver avoids being misled by an internal DNS server or a local cache:
Resolve-DnsName -Name selector1._domainkey.contoso.com -Type CNAME -Server 8.8.8.8
Resolve-DnsName -Name selector2._domainkey.contoso.com -Type CNAME -Server 8.8.8.8Compare the returned target with Selector1CNAME and Selector2CNAME. On Linux or macOS the same check is:
dig +short CNAME selector1._domainkey.contoso.com @8.8.8.8
dig +short CNAME selector2._domainkey.contoso.com @8.8.8.8DNS tools often show the target with a trailing period (...dkim.mail.microsoft.); that is just the fully qualified form and isn't a mismatch. If the query returns nothing, the record isn't published where the internet can see it, or the host name is wrong.
Step 4: Enable DKIM signing
Microsoft says it takes a few minutes, or possibly longer, for Microsoft 365 to detect new CNAME records. Once the public check passes, enable signing:
Set-DkimSigningConfig -Identity contoso.com -Enabled $true
Get-DkimSigningConfig -Identity contoso.com | Format-List Name,Enabled,StatusIf Microsoft 365 detects the records, the command completes without error and the domain shows Enabled : True and Status : Valid. If it doesn't, you get an error containing the values the records must have.
In the Defender portal, open the domain's details flyout on the DKIM tab and select the Sign messages for this domain with DKIM signatures toggle. A dialog says it may take several minutes to synchronize the status change. When the records are detected, the toggle stays Enabled, the status reads Signing DKIM signatures for this domain, Rotate DKIM keys becomes available and Last checked date updates.
Verify that outbound mail is signed
Wait a few minutes after enabling, then send a message from a mailbox in the domain to an external mailbox. Avoid AOL for this test; Microsoft notes it might skip the DKIM check if SPF passes. In the received message's headers, look for a DKIM-Signature header with your domain and a selector:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=contoso.com;
s=selector1;Then look for dkim=pass with header.d=contoso.com in the receiving system's Authentication-Results header. The s= value tells you which selector, and therefore which key, signed the message.
Troubleshooting
"CNAME record does not exist for this config. Please publish the following two CNAME records first."
This is the text administrators report from both the portal and PowerShell, often prefixed with Microsoft.Exchange.Management.Tasks.ValidationException. It means the detection hasn't found matching records yet. Work through the checks in order: public resolution (Step 3), exact host name, exact value, then time. If the error shows the placeholders {0} {1} instead of record values, get the values from Get-DkimSigningConfig instead.
Records exist but contain an old-format value
If your records point to ...contoso.onmicrosoft.com but Get-DkimSigningConfig shows a ...dkim.mail.microsoft value (or the other way round), replace the records with the values Microsoft 365 shows now. The formats can't be mixed for a selector.
The domain moved to a different tenant
The CNAME target contains the initial domain prefix of the tenant that holds the keys. After a tenant-to-tenant move, the existing records still point to the source tenant's keys, so the target tenant reports CnameMissing. Create the configuration in the target tenant, replace both records with its values and enable signing there. The cutover plans in Microsoft 365 tenant-to-tenant migration and Google Workspace to Microsoft 365 migration both include this DNS step.
Only one of two domains signs
Each domain needs its own pair of records. Run Get-DkimSigningConfig without -Identity and check every row: any domain that still shows CnameMissing or Enabled : False needs its own records published and signing enabled.
Receivers don't see a signature from your domain
Until the custom domain is signing, receivers don't see a DKIM-Signature with d= set to your domain, so DKIM can't align with the From domain for DMARC. Confirm Enabled is True and Status is Valid, then send a new test message after a few minutes, because messages sent before the change aren't re-signed.
Parked domains
Don't publish DKIM records for registered domains that never send mail. Microsoft's guidance is that the absence of a public key prevents DKIM validation of forged messages that claim to come from those domains.
After it works: move to 2048-bit keys
If you created keys at the default 1024 bits, rotate to 2048 bits:
Rotate-DkimSigningConfig -Identity contoso.com -KeySize 2048
Get-DkimSigningConfig -Identity contoso.com |
Format-List Selector1KeySize,Selector2KeySize,RotateOnDate,SelectorBeforeRotateOnDate,SelectorAfterRotateOnDateRotation isn't immediate: the new key starts signing after four days (96 hours), and you can't start another rotation while one is in progress. The new size applies to the next active selector, so the other selector is upgraded on the following rotation.
Checklist
Get-DkimSigningConfigrun for every sending domain and subdomain; values copied, not built by hand.- Two CNAME records per domain, host names
selector1._domainkeyandselector2._domainkey, no doubled zone name. - Both records resolve from a public resolver to the exact expected targets.
Set-DkimSigningConfig -Enabled $truesucceeds; statusValid.- Test message shows
d=your domain anddkim=passat an external receiver. - DMARC record in place, and parked domains left without DKIM records.
- 2048-bit rotation scheduled if the keys were created at 1024 bits.
If mail from your domain still lands in Junk at other organizations once DKIM passes, read the receiver's headers as described in Microsoft 365 email landing in Junk.
References
- How to use DKIM for email in your custom domain
- New-DkimSigningConfig
- Connect your domain by adding DNS records
- Resolve-DnsName
- Find the permissions required to run any Exchange cmdlet
- Microsoft Q&A: CNAME record does not exist for this config
- Microsoft Q&A: DKIM CNAME records exist but the portal still shows the error