How to Add DKIM, SPF, and DMARC Records in Cloudflare

Flat illustration of a blue cloud above a stack of three record cards, with a navy key slotted into the top card.

In the Cloudflare dashboard, open your domain, go to DNS > Records, select Add record, and create the record your sending provider gave you. Providers hand out DKIM either as a TXT record (the public key itself) or as a CNAME (a pointer to a key the provider hosts). In the Name field, enter only the selector part, such as s1._domainkey, not the full hostname. If the record is a CNAME, set its proxy status to DNS only (grey cloud). Cloudflare’s own docs recommend DNS only for records used for email, and a proxied CNAME stops providers from finding the record.

Sample values use example.com and placeholder selectors. For background, see how DKIM works and SPF, DKIM, and DMARC together.

What to collect before you open Cloudflare

Copy these from your email provider’s domain-authentication screen:

  1. The record type (TXT or CNAME).
  2. The Name or Host value. For DKIM this is the DKIM selector plus ._domainkey, for example s1._domainkey.
  3. The Value or Content: either a string starting with v=DKIM1; k=rsa; p=... or a hostname owned by the provider.

Then confirm Cloudflare actually answers DNS for the domain. Records added in Cloudflare only take effect if the domain’s nameservers point to Cloudflare. Cloudflare’s nameserver documentation says that “for these nameservers to be authoritative for your domain, you need to update your domain nameservers.” Check with dig NS example.com +short: the answer should be two names ending in ns.cloudflare.com. If it shows your registrar’s or another host’s nameservers, edit DNS there instead.

Add a DKIM record in Cloudflare

Cloudflare’s instructions for creating records are: go to the DNS Records page, select Add record, choose a Type, complete the required fields, and select Save.

Variant 1: TXT record with the public key

FieldValue
TypeTXT
Names1._domainkey
Contentv=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8...
TTLAuto

Paste the value exactly as the provider shows it, on one line. Cloudflare’s documentation says that “if you save your TXT content without any quotes, Cloudflare will automatically add double quotes,” and warns of validation errors when quotation marks are inconsistent. So leave your own quotes out. TXT records are never proxied; the proxy status docs list TXT among the types that are “always DNS-only.”

Long 2048-bit keys. A 2048-bit key is longer than the 255 bytes a single DNS text string can hold, so it is published as several strings that receivers join back together. RFC 6376 requires that “strings in a TXT RR MUST be concatenated together before use with no intervening whitespace.” Cloudflare’s record documentation sets a maximum of 4,096 bytes per record and does not describe string splitting, so paste the full key as one value and verify with dig afterward (see below). If a lookup shows a truncated p= value, re-paste the key without line breaks.

Variant 2: CNAME record pointing to the provider

Many providers host the key themselves and ask for CNAMEs instead. Amazon SES Easy DKIM is one: its documentation tells you to copy “the three CNAME records” into your DNS, each one named selector._domainkey and pointing to a value like token.dkim.us-west-2.amazonses.com. SendGrid’s domain authentication uses CNAME records too.

FieldValue
TypeCNAME
Names1._domainkey
Targets1.domainkey.u1234.wl.provider.example
Proxy statusDNS only
TTLAuto

A DKIM CNAME must be DNS only. Cloudflare’s proxy status documentation says only A, AAAA, and CNAME records can be proxied, and that records used for email or domain verification should not be: “Certain DNS records should be DNS-only because the services they support are not compatible with Cloudflare’s HTTP proxy.” A proxied CNAME answers with Cloudflare addresses instead of the provider’s hostname, so the receiver never reaches the key. Cloudflare’s CNAME documentation gives the effect: “a query for TXT in abc.example.com will not return the TXT content in the target zone.”

Enter the selector, not the full hostname. Cloudflare’s guide to subdomain records says to “use your subdomain (blog) for the record Name.” Do the same here: type s1._domainkey. Pasting s1._domainkey.example.com is how people end up with a record at s1._domainkey.example.com.example.com, which no receiver will ever query. Amazon’s SES documentation warns that “some providers append the domain name without indicating that they’ve done so,” so after saving, look at the record in the list and test it with dig.

Add or update SPF in Cloudflare

SPF is a TXT record at the root of the domain, which Cloudflare’s Name field calls the zone apex (@).

FieldValue
TypeTXT
Name@
Contentv=spf1 include:_spf.provider.example include:spf.other-sender.example ~all

A domain gets one SPF record. RFC 7208 is explicit: if the lookup returns more than one SPF record, the result is “permerror,” and the check fails. When you add a second sending service, edit the existing record and add another include: instead of creating a new TXT record. SPF also limits evaluation to 10 DNS-querying terms: “SPF implementations MUST limit the total number of those terms to 10 during SPF evaluation.” Stacking includes from many tools can break SPF silently; the details are in our guide to SPF record syntax.

Some providers handle SPF through their own CNAME records instead, so check what yours asks for before adding an include.

Add a DMARC record in Cloudflare

DMARC lives in a TXT record on the _dmarc label.

FieldValue
TypeTXT
Name_dmarc
Contentv=DMARC1; p=none; rua=mailto:[email protected]

Start at p=none: receivers deliver mail normally and send you aggregate reports, so nothing breaks while you learn who sends as your domain. Moving to quarantine and reject comes later, once the reports are clean; the steps are in our guide to setting up DMARC, and the rua address will receive DMARC aggregate reports as XML files.

Cloudflare also offers DMARC Management (in the dashboard under Email, then DMARC Management). Its documentation describes it as a tool that “helps you track every source that is sending emails from your domain,” shows whether messages pass SPF, DKIM, and DMARC, and is “available to all Cloudflare customers with Cloudflare DNS.” The documentation does not use the word “free,” so check Cloudflare’s pricing page for billing. It reads reports; the DKIM record your provider needs still has to be added by you.

Verify the records with dig

Run these from a terminal and compare the output with what your provider gave you:

dig TXT s1._domainkey.example.com +short
dig TXT example.com +short
dig TXT _dmarc.example.com +short
dig CNAME s1._domainkey.example.com +short   # for CNAME-style DKIM

A correct TXT lookup for DKIM returns a string beginning v=DKIM1 with a p= value. A correct CNAME lookup returns the provider’s hostname, not a Cloudflare IP address. Then use the provider’s own verify button.

How fast it works. Cloudflare’s TTL documentation says that “a TTL of Auto is set to 300 seconds (five minutes),” so Cloudflare-side changes should reach resolvers within about that window. Provider-side verification can lag: Amazon SES, for example, says DNS changes “can take up to 72 hours to propagate.”

Troubleshooting DKIM, SPF, and DMARC on Cloudflare

SymptomLikely causeFix
Provider says the DKIM CNAME is missing, but it is in the dashboardCNAME is proxied (orange cloud)Edit the record and set proxy status to DNS only
dig returns nothing for s1._domainkey.example.com, but a record existsDoubled hostname: the record sits at s1._domainkey.example.com.example.comDelete it and re-add with Name s1._domainkey only
SPF shows permerror or two results from dig TXT example.comTwo v=spf1 recordsMerge both into one record, one v=spf1 and all include: terms
SPF permerror with a single recordMore than 10 DNS-querying termsRemove unused includes (see SPF record syntax)
DKIM p= value fails to parseStray quotes, spaces, or line breaks pasted into the keyRe-paste the key on one line, no quotes; confirm with dig
Records resolve in the dashboard but not publiclyDomain nameservers are not Cloudflare’sRun dig NS example.com +short; add records where the nameservers point, or move them to Cloudflare
Added to the wrong domainRecord created in a different zone (for example the parent domain instead of the sending subdomain)Open the zone for the exact domain in your From address
Provider cannot verify a CNAME even when DNS onlyCNAME flattening turned the CNAME into an A recordCloudflare notes flattening “can prevent email providers from reading the record correctly” and that you may need to turn it off

Frequently Asked Questions

How do I add a DKIM record in Cloudflare?

Open the domain, go to DNS > Records, select Add record, choose TXT or CNAME as your provider specifies, enter the selector (for example s1._domainkey) as the Name, paste the Content or target, and save. For CNAMEs, set the proxy status to DNS only.

Should DKIM CNAME records be proxied in Cloudflare?

No. Cloudflare’s docs say records used for email should be DNS only, because the proxy only handles HTTP and HTTPS traffic. A proxied CNAME returns Cloudflare addresses, so receivers cannot find the provider’s DKIM key.

Does Cloudflare generate DKIM keys for me?

Only for its own services. Cloudflare’s Email Routing and Email Sending create DKIM records with their own selectors (cf2024-1._domainkey for Routing, cf-bounce._domainkey for Sending). Those cover mail Cloudflare forwards or sends. They do not sign mail from another provider such as SendGrid, SES, or your own platform. DMARC Management monitors authentication but, per the documentation, does not create your provider’s keys.

Can I have two SPF records in Cloudflare?

No. RFC 7208 says a lookup that returns more than one SPF record produces a “permerror.” Combine all senders into one TXT record starting with v=spf1, using one include: per service.

How long does a DNS change take to work on Cloudflare?

Auto TTL is 300 seconds (five minutes), so expect changes within about that window. Some providers re-check on a schedule; Amazon SES says DNS changes can take up to 72 hours to propagate.

Does Cloudflare support 2048-bit DKIM keys?

Yes, as a TXT value. Cloudflare allows up to 4,096 bytes per record, which fits a 2048-bit public key. Paste it on one line without quotes, as Cloudflare adds them, and confirm with dig that the full p= value comes back.