Microsoft 365 signs outbound mail by default, but with your tenant's onmicrosoft.com domain as the signing domain. That signature is valid and useless for DMARC, because it does not align with the From address your recipients see. To get aligned DKIM you publish two CNAMEs for your custom domain and enable signing for it. Order matters: the CNAMEs first, then the toggle.
Step 1: publish the two selector CNAMEs
Microsoft uses two selectors so it can rotate keys without an interruption — one is live while the other holds the next key. The pattern is:
| Type | Host | Points to |
|---|---|---|
| CNAME | selector1._domainkey.yourdomain.com | selector1-yourdomain-com._domainkey.<tenant>.onmicrosoft.com |
| CNAME | selector2._domainkey.yourdomain.com | selector2-yourdomain-com._domainkey.<tenant>.onmicrosoft.com |
Two things to get exactly right:
- The dots in your domain become dashes inside the target (
yourdomain.combecomesyourdomain-com). A domain with a hyphen already in it keeps the hyphen, which is the usual source of a typo. <tenant>is your initial Microsoft tenant name, the one ending.onmicrosoft.com. Read it from the Microsoft 365 admin centre rather than guessing.
The Defender portal shows both target values for you; copy them from there. If your DNS panel appends the zone name automatically, enter only selector1._domainkey as the host, not the fully qualified name — otherwise you create selector1._domainkey.yourdomain.com.yourdomain.com.
Step 2: enable signing
In the Microsoft Defender portal, go to *Email & collaboration* → *Policies & rules* → *Threat policies* → *Email authentication settings* → *DKIM*, select your domain, and switch *Sign messages for this domain with DKIM signatures* on.
Or in Exchange Online PowerShell:
Connect-ExchangeOnline New-DkimSigningConfig -DomainName yourdomain.com -Enabled $true -KeySize 2048 Get-DkimSigningConfig -Identity yourdomain.com | Format-List
If the CNAMEs have not propagated, you get a refusal naming the missing CNAME record for the configuration. That error is accurate: go back, run dig, and wait out the TTL rather than retrying the toggle.
Step 3: verify from outside Microsoft
dig +short CNAME selector1._domainkey.yourdomain.com dig +short TXT selector1._domainkey.yourdomain.com dig +short CNAME selector2._domainkey.yourdomain.com
The TXT query should return a v=DKIM1; k=rsa; p=... value even though you published a CNAME — that is the resolver following the chain into Microsoft's zone. Then send a message to an external mailbox you control and read the headers:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yourdomain.com; s=selector1; h=from:date:subject:mime-version:content-type; bh=...; b=... Authentication-Results: mx.google.com; spf=pass smtp.mailfrom=yourdomain.com; dkim=pass header.i=@yourdomain.com; dmarc=pass (p=NONE) header.from=yourdomain.com
d=yourdomain.com is the whole point. If it still says <tenant>.onmicrosoft.com, signing for your custom domain is not active and DMARC has nothing aligned to pass on apart from SPF.
Key size and rotation
Microsoft supports 2048-bit keys, and an older configuration may still be on 1024-bit. Rotate:
Rotate-DkimSigningConfig -Identity yourdomain.com -KeySize 2048
Rotation is why there are two selectors: Microsoft signs with one while publishing the next key under the other, then swaps. You do not need to change your CNAMEs to rotate, which is the main advantage of the CNAME approach over publishing raw public keys — no 255-character TXT string splitting, no manual republication.
Where SPF and DMARC fit
SPF for Microsoft 365, merged into your single existing record:
v=spf1 include:spf.protection.outlook.com -all
One v=spf1 record per domain. Two produces PermError and disables SPF for everything. Keep inside SPF's limit of 10 DNS-querying mechanisms; include:spf.protection.outlook.com consumes several on its own.
Then DMARC, starting in monitor mode:
_dmarc.yourdomain.com TXT "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; fo=1"
Add sp= when you tighten p=, so subdomains do not inherit a policy you have not tested them against.
Troubleshooting
- `dkim=none` on delivered mail. Signing is off for the domain, or the mail left through a route that bypasses Exchange Online — a device, an application relay or a third-party platform. Each of those needs its own DKIM setup; enabling it in Microsoft 365 does not sign mail Microsoft never handled.
- `dkim=fail` with "body hash did not verify". Something altered the message after signing. The usual suspects are an appliance or mailing list appending a footer. The signature is working correctly and reporting a real modification.
- `dkim=permerror`. The selector in the message's
s=tag does not resolve. Query that exact selector; do not assume it isselector1. - It worked and then stopped. Check whether someone recreated the CNAME as a TXT record, or whether a DNS migration dropped the
_domainkeynames. Underscore-prefixed records are the ones migrations lose.
What not to do
- Do not enable DKIM before the CNAMEs resolve. You will get a refusal and may conclude, wrongly, that the record values are wrong.
- Do not publish Microsoft's selector targets as TXT records. They are CNAMEs; the key lives in Microsoft's zone.
- Do not rely on the default
onmicrosoft.comsignature. It is not aligned with yourFromdomain. - Do not delete
selector2because nothing seems to use it. Rotation needs both. - Do not assume one passing test covers every path. Test from Microsoft 365, and separately from every other platform that sends with your domain.
MailPilot checks SPF, DKIM and DMARC for each connected mailbox's domain and warms Microsoft 365 and Outlook mailboxes over OAuth, so an unaligned signature or a lost _domainkey record shows up as a failing check instead of as unexplained filtering.
Ready to reach the inbox every time?
Automated email warmup across real peer mailboxes. Live inbox placement monitoring. Free 7-day trial - no credit card required.
Start free trial