Fixing this for a Microsoft 365 domain
Two of the three records live in DNS rather than in Microsoft 365. Here's what goes where.
Worth knowing before you start: most of this is not done in Microsoft 365. Two of the three records live purely in DNS, wherever your nameservers point, which may be a completely different company. Only DKIM involves the Microsoft admin portal.
Where each change is made
- SPF — a TXT record at your DNS provider. Nothing to do in Microsoft 365.
- DMARC — a TXT record at your DNS provider. Nothing to do in Microsoft 365.
- DKIM — Microsoft gives you two CNAME records rather than a TXT one. You publish those at your DNS provider, then go back to the admin portal to switch signing on.
The check tells you who hosts your DNS. It's often not the company you bought the domain from.
1. Turn on DKIM
In the Microsoft 365 Defender portal, open
Email & collaboration → Policies & rules → Threat policies → Email
authentication settings → DKIM, then select your domain. Microsoft shows you two
CNAME records to publish. Copy those exact host and target values — do not reconstruct them
by hand. Newer domains use a dkim.mail.microsoft target rather than the older
onmicrosoft.com shape, and the two formats cannot coexist for the same selector.
Once both records are live, come back to the same screen and switch DKIM signing on for the domain.
It's first for a reason. When a message is forwarded on — by a role address like
finance@ that points at whoever currently holds the job, or an old alumni address
that redirects — SPF generally breaks, because the message now reaches the recipient from the
forwarder's server rather than from Microsoft's, while a DKIM signature survives that trip
intact. So DKIM is what keeps that mail passing once you tighten the policy, and a domain relying
on SPF alone has nothing protecting it.
Mailing lists are the harder case, and DKIM does not rescue them: most lists add a footer or tag
the subject, which invalidates the signature as well. That is why list software rewrites the
From: header, and why the advice further down is to stop at quarantine.
2. Check SPF
A single TXT record at your domain root. If you already have one, edit it rather than adding a second — two SPF records break SPF entirely, and replacing an existing record wholesale drops whatever senders were already listed in it.
v=spf1 include:spf.protection.outlook.com ~all Anything else that sends as your domain needs adding to this same record.
The record above ends ~all, which tells receivers that mail from anywhere
unlisted is suspect without asking them to refuse it. There is a stricter ending,
-all, which does ask them to refuse it.
~all is a perfectly reasonable place to stay. The reason is
forwarding again: when a message is forwarded on, SPF fails because it now arrives from the
forwarder's server, and a receiver can act on an SPF hard fail during delivery — before it
ever looks at the DKIM signature that survived the trip. Those refusals don't appear in your
DMARC reports either, so you wouldn't find out. With ~all that mail still gets
through on DKIM, which is what you set up in step 1. Your protection against forgery comes
from the DMARC policy below, and DMARC treats a soft fail and a hard fail identically.
-all is worth it if you are confident every legitimate sender is listed and
nobody forwards your mail — a domain used only for bulk sending, say. It also takes effect
the moment you publish it, with no monitoring stage of the kind DMARC gives you.
Microsoft's own documentation gives -all in its example while also describing
~all while you are still discovering senders. For a small organisation whose
mail gets forwarded, staying on ~all is the safer of the two.
3. Add DMARC, then tighten it
TXT record with the host _dmarc:
v=DMARC1; p=none; rua=mailto:[email protected];
Use a mailbox that exists, or an address from a reporting service. On a domain with no DMARC
policy in force, p=none changes nothing about delivery.
One thing to check before publishing it. If the check says this exact name
is already inheriting quarantine or reject from a parent domain, then
publishing a weaker policy here replaces that inherited protection — and you don't want
this record. p=none turns it off entirely; p=quarantine weakens
inherited reject. Inheriting a parent's p=none, or a parent
whose sp= already sets none for its subdomains, is a different case —
there is nothing to lose and the record is fine to add. Go by the effective policy the check
reports for this name, not by what the parent's record says on its own.
Reports arrive only from receivers that choose to send them, and if the address is on someone else's domain that domain has to authorise it first — so a quiet period means "check the address" rather than "nobody is forging you". The ones that do arrive are zipped XML files built for software rather than people, so you'll need something to summarise them. See making DMARC reports readable.
Then, once the reports show every legitimate sender passing, move to
p=quarantine. A short clean window can still miss senders that only go out
quarterly or once a year — ask who uses the domain before you tighten.
Quarantine is the right place to stop for most organisations. The stricter
p=reject refuses forged mail outright, but the current DMARC standard advises
against it for ordinary organisations: a mailing list relays your message from its own servers
while leaving your address in the From line, so genuine mail sent that way is refused too, and
people can be dropped from the list without noticing.
If another organisation sends email as you
This is common where a management company or fiscal sponsor handles some of your mail. Their DKIM signs as their domain, which fails DMARC alignment even though their own setup is fine.
The fix is on their side: they add your domain to their tenant and publish DKIM records for
it, so the signature carries your domain rather than theirs. Find those senders during the
monitoring period — under p=quarantine their mail goes to spam, and under
p=reject it is refused, until their DKIM is aligned to your domain.