Setting up DMARC, SPF and DKIM in Cloudflare DNS
By Thomas · virtual CISO · 2026-07-25
"Adding DMARC in Cloudflare" is a search that comes up constantly, and it gets something right. In a DMARC rollout, the mailbox provider supplies values, but it's the host of the DNS zone that publishes them — and for an enormous share of the web, that zone lives at Cloudflare. The mailboxes may sit in Microsoft 365 or Google Workspace, the campaigns may leave from Brevo, Mailchimp or Amazon SES: it makes no difference. SPF, DKIM and DMARC are DNS records, and they go wherever the DNS is authoritative.
The good news: everything fits in a handful of TXT records, plus, depending on the provider, one or two CNAMEs for the DKIM selectors. The less good news: Cloudflare has its quirks — an orange cloud that has no business on a selector CNAME, an "Auto" TTL whose actual value is worth knowing, a "flattening" that shares a name with an SPF technique it has nothing to do with, and a built-in DMARC tool best understood before anything gets clicked.
This guide walks through creating the three records in the Cloudflare dashboard, the platform-specific settings, the most frequent mistakes and the final verification — independently of whichever mail system sits behind the domain.
Cloudflare does the DNS, not the mail
A recurring confusion: "the mail is at Microsoft, why touch Cloudflare?" Because authentication records belong to the zone, not to the mail server. As soon as the domain's nameservers point at Cloudflare — which is the case the moment a domain is activated there, free plan included — everything happens in the dashboard, under the DNS tab. The mail provider supplies the values (the SPF include:, the DKIM key or CNAMEs); Cloudflare publishes them; receiving servers read them.
Any doubt about who is authoritative clears up in ten seconds:
dig NS example.com +short
If the answer ends in ns.cloudflare.com, the zone is indeed at Cloudflare, and any change made elsewhere — at the registrar, at a former DNS host — will go nowhere. The approach described here transposes almost as-is to other DNS hosts: setting up SPF and DKIM at OVHcloud or at Gandi follows exactly the same logic; only the interface and a couple of reflexes differ.
DMARC: a TXT record at _dmarc
Creation goes through DNS → Records → Add record:
Type : TXT
Name : _dmarc
Content : v=DMARC1; p=none; rua=mailto:reports@example.com
TTL : Auto
Two interface details matter. The Name field expects the relative part of the name: typing _dmarc is enough, the platform expands it to _dmarc.example.com (the full name is accepted too and gets normalized). And the underscore is part of the name: a record placed at dmarc, without it, will never be queried by anyone. The content is pasted as-is, without quotes — the interface handles them.
On substance, p=none is the sane starting point: the domain blocks nothing, but starts receiving aggregate reports at the address declared in rua. Hardening — p=quarantine, then p=reject — comes after the source inventory, never before. A note for older memories: the current standard, DMARCbis, dropped the pct tag (gradual rollout now goes through the t=y test mode) and added np for non-existent subdomains; v=DMARC1 remains the expected value, backward compatibility is complete. To pick the right policy and options for each situation — active domain, parked domain, sending subdomain — annotated DMARC record examples provide templates ready to adapt.
SPF at the root, DKIM in the provider's format
SPF first. It's a TXT placed at the zone apex: in the Name field, @ stands for the domain itself.
Type : TXT
Name : @
Content : v=spf1 include:spf.protection.outlook.com include:_spf.brevo.com -all
The value aggregates every legitimate sender, each through its include:. One absolute rule: a single record starting with v=spf1 per name. A new sender gets added inside the existing record, never as a second TXT.
DKIM next — and here the provider dictates the format. Two schools coexist:
- Direct TXT: the provider hands over a public key to paste. Google Workspace, for instance: Name
google._domainkey, contentv=DKIM1; k=rsa; p=MIIBIjANBg…. - Delegation CNAME: the provider hands over one or more aliases pointing at its own servers, where the key lives — and rotates without anyone lifting a finger. Microsoft 365 asks for two:
selector1._domainkeyandselector2._domainkey, pointing atselector1-example-com._domainkey.example.onmicrosoft.comand its twin. SendGrid, Mailjet or Brevo do the same with their own names (s1._domainkey,s2._domainkey…).
Both formats are created in the same place, choosing type TXT or CNAME. CNAME delegation has a genuine advantage — key rotation becomes the provider's problem — but at Cloudflare it raises one specific question, covered two sections below.
What is Cloudflare-specific
Three particularities set the platform apart from classic DNS interfaces.
Proxy status is moot for TXT records. The famous orange cloud — the proxy that routes web traffic through Cloudflare's network — only applies to A, AAAA and CNAME records. TXT records (_dmarc, SPF, a pasted DKIM key) simply don't carry that toggle: no decision to make, no way to get it wrong. The question only arises for selector CNAMEs, and it's covered right after.
The "Auto" TTL is 300 seconds. For a non-proxied record, "Auto" means five minutes. That's an excellent setting for authentication records: a fix propagates fast, a mistake gets corrected fast. Nothing requires changing it, and hunting for a long TTL "to spare the servers" is pointless on an anycast network of that scale.
A "DMARC Management" tool is built in. In the zone's email section, the platform offers a module that publishes the _dmarc record and collects aggregate reports at a Cloudflare-hosted rua address, with charts in the dashboard. It's a feature of the DNS platform, free of charge, and it can serve as a first contact with aggregate reports. One point is worth knowing before activating anything: the rua tag accepts several addresses, comma-separated. The Cloudflare collection address can therefore coexist with another destination — and choosing the DMARC report reception address deserves its own reflection, because it conditions everything that follows.
Selector CNAMEs: grey cloud mandatory, "flattening" worth knowing
Cloudflare's number-one email trap fits in a color. When a CNAME gets created, the interface readily offers the proxy (orange cloud). For a website that's often the right call; for a DKIM selector it's fatal. A proxied CNAME disappears from public view: Cloudflare answers in its place with its own IP addresses to serve web traffic, and a TXT query for selector1._domainkey.example.com returns nothing at all. The key becomes unreachable, DKIM signatures fail, and DMARC alignment hangs on SPF alone. Every selector CNAME must therefore stay on "DNS only" — grey cloud. The telltale symptom of an oversight: the mail provider reports "record not found" while the CNAME sits in plain sight in the dashboard.
Second subtlety: CNAME flattening. At the zone apex, Cloudflare flattens CNAMEs systematically — the protocol forbids a CNAME at the root, so the platform resolves it itself and serves the result directly. An option extends that flattening to every CNAME in the zone. Applied to a DKIM selector, flattening doesn't break validation: resolution stays dynamic, the final content is served, the provider's key rotation is followed. But the chain becomes invisible in diagnostics, which complicates debugging the day something goes wrong. Absent a specific need, selectors read better unflattened. The homonym, finally, invites confusion: this CNAME flattening has nothing to do with "SPF flattening", which consists of replacing include: mechanisms with IP addresses to dodge the ten-DNS-lookup limit — a last-resort technique with well-documented downsides.
The common mistakes
The record placed in the wrong spot. A _dmarc shorn of its underscore, an SPF placed on www instead of the apex, or — subtler — a policy expected on a dedicated sending subdomain but placed on the zone. Under DMARCbis, a subdomain without a record of its own inherits the organizational domain's policy through the DNS Tree Walk; to give news.example.com a policy of its own, the record goes at _dmarc.news. In the other direction, a record stranded on a fanciful name will simply never be read.
Duplicates. Cloudflare happily accepts two v=spf1 TXT records on the same name — and that duplicate voids SPF (permerror) at every receiver. Same sanction for two records at _dmarc: faced with several policies, servers apply none. Before any creation, a pass through the list of existing records avoids the collision, especially after a sending-provider switch where the old record still lingers.
The duplicated zone. Two flavors of the same ailment. First, the domain added to Cloudflare without the nameservers being switched at the registrar: the Cloudflare zone exists, edits apply diligently… and nobody ever queries it — changes have no effect while the old zone keeps answering. Second, inbound migration: on importing a domain, Cloudflare scans the origin zone to copy its records, and that scan readily misses the less standard TXT entries — _dmarc, selectors under _domainkey. A migrated domain can thus lose its DKIM overnight without anything having been consciously "deleted". After any migration, a line-by-line comparison with the old zone is in order.
Verify, then observe
Propagation is fast at Cloudflare — five-minute Auto TTL, anycast network — and verification can follow creation within minutes. On the command line:
dig TXT _dmarc.example.com +short
dig TXT example.com +short
dig TXT selector1._domainkey.example.com +short
The first query must return the DMARC policy, the second the SPF record (among other possible TXT entries), the third the DKIM key — including through a CNAME, which dig follows silently. An empty answer on a selector that sits visibly in the dashboard almost always signals a forgotten orange cloud.
DNS verification is only half the journey, though. The definitive proof is the aggregate reports arriving at the rua address and confirming, source by source, that SPF and DKIM pass and align. On that basis — data, not guesses — the policy can climb from p=none to p=quarantine, then p=reject.
In summary
Cloudflare hosts the zone, the mail lives elsewhere, and everything goes in the DNS tab: a _dmarc TXT at p=none with a rua address, a single v=spf1 TXT at the apex, DKIM selectors as TXT or CNAME depending on the provider. The platform-specific reflexes fit in four points: grey cloud mandatory on selector CNAMEs, Auto TTL left alone, flattening confined to the apex, vigilance on duplicates and on ghost zones after a migration. The built-in DMARC tool can bootstrap collection; the multi-address rua tag keeps every door open.
To validate the result in one pass — DMARC record, SPF, selectors, alignment — a free DMARC analysis of the domain draws up the full picture in seconds. And once the first reports come in, creating an account opens the next stage: source inventory, alerts on newcomers, and a gradual climb to p=reject at whatever pace the domain's ecosystem allows.
Enforcing DMARC, in practice
Thomas, the virtual CISO of DMARC.com, identifies every legitimate sending source, writes the exact DNS records, and takes a domain from p=none to p=reject — without breaking its mail.
Get to p=reject — freeRelated guides
- Configuring SPF and DKIM at Gandi
GandiMail, LiveDNS, the _mailcust.gandi.net include, the gm1 to gm3 DKIM selectors: the complete path to authenticating email for a domain hosted at Gandi.
- Setting up SPF and DKIM on OVHcloud
MX Plan, Email Pro or Exchange: each OVHcloud email plan has its own SPF and DKIM records. DNS zone, the default SPF trap, CNAME selectors and verification.
- Not receiving DMARC reports: the causes and the fix
A DMARC record is published, but no reports arrive. Here are the possible causes, in the order to check them, from the most common to the most subtle.
About the author
Thomas — Thomas is the virtual CISO of DMARC.com: a copilot specialized in email authentication that walks organizations from p=none to p=reject without breaking their mail. His guides draw on real data from the DMARC Observatory and the RUA reports the platform analyzes.
