Skip to main content

Getting SPF, DKIM and DMARC Right for a WordPress Site That Sends Through Cloudflare

• Tom Morton

If you have installed Flarepipe: Email and the test message arrived, the plumbing works. Whether your receipts and password resets keep arriving, in the inbox rather than the spam folder, is decided by three DNS records. Gmail, Yahoo and Outlook check all three on every message, and a missing record is the most common reason a correctly sent WordPress email never gets read.

The worked example below is flarepipe.com’s own records, because they are the same records your site needs, and the proof at the end is the headers of a delivered message rather than a green check in a settings screen.

What the three records do

SPF, Sender Policy Framework, is a TXT record listing the servers allowed to send mail for a domain. The receiving server looks up the domain in the message’s envelope sender (the bounce address, not the address you see in the From line) and checks the connecting server is on the list.

DKIM, DomainKeys Identified Mail, is a signature. The sending service signs each message with a private key, and publishes the public key in a TXT record under a _domainkey name on your domain. The receiver fetches the key and checks the signature, which proves the message was not altered and that whoever signed it controls your DNS.

DMARC tells receivers what to do when a message claiming to be from your domain fails both of the above, and asks them to send you reports. It also adds an alignment rule: at least one of SPF or DKIM has to pass for a domain that matches the one in the From header.

Which records Cloudflare handles

Flarepipe: Email sends through Cloudflare’s Email Sending service, using your own account and a token scoped to Account > Email Sending > Edit. Before the plugin can send, your domain has to be onboarded in the Cloudflare dashboard under Build > Compute > Email Service > Email Sending, which is step one of the Cloudflare setup guide.

Onboarding is where Cloudflare generates the records it needs to sign and bounce mail for the domain: a DKIM public key under a _domainkey name, and MX and SPF records on a dedicated bounce subdomain. When your DNS is on Cloudflare, which it is if you are using the plugin, those records are added to the zone for you. Open the DNS tab for the domain and look for a TXT record whose name contains _domainkey before you assume it is there. If it is missing, revisit the onboarding screen; the plugin cannot sign mail for a domain Cloudflare has not finished setting up.

On flarepipe.com it looks like this. Our own site sends login codes and support replies from support@flarepipe.com through the same service the plugin uses. Open one of those messages in Gmail, choose Show original, and the authentication summary reads:

dkim=pass header.i=@flarepipe.com header.s=cf-bounce
spf=pass smtp.mailfrom=bounces@cf-bounce.flarepipe.com
dmarc=pass

The envelope sender is on the cf-bounce.flarepipe.com subdomain, which carries Cloudflare’s SPF include and MX records, so SPF passes against the subdomain. The DKIM key lives at cf-bounce._domainkey.flarepipe.com and signs for flarepipe.com itself, so the signature domain matches the From domain exactly. And because a subdomain of the From domain counts as aligned, DMARC is satisfied twice over. The apex SPF record on flarepipe.com only lists Google Workspace, which handles the human mailboxes, and that is fine, because Cloudflare never uses the apex as an envelope sender.

SPF: one record, merged

The DNS records guide recommends adding Cloudflare’s include to the SPF record on your root domain:

v=spf1 include:_spf.mx.cloudflare.net ~all

The rule that catches people is that a domain may have exactly one SPF record. If you already have one for Google Workspace, Microsoft 365 or a newsletter service, do not add a second TXT record. Two SPF records is a permanent error, and receivers treat a permanent error as a failure for every sender, including the ones that were working. Merge instead:

v=spf1 include:_spf.google.com include:_spf.mx.cloudflare.net ~all

Keep the ~all at the end, and keep the total number of DNS lookups the record triggers under ten, which is the limit receivers enforce. Each include: costs at least one.

DKIM: check, do not create

You do not generate a DKIM key for Cloudflare. The key pair is Cloudflare’s, created at onboarding, and the public half is the _domainkey TXT record you checked for above. Never edit that record by hand: a key that no longer matches the private half produces dkim=fail on every message until it is restored.

DMARC: start loose, then tighten

Add a TXT record named _dmarc on your domain. The safe starting point is monitoring only:

v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com

p=none tells receivers to deliver as normal but send you aggregate reports at the rua address. Run that for a couple of weeks and read the reports: every legitimate source of mail for your domain should be passing. Once they are, move to p=quarantine, which sends failing mail to spam, and finally to p=reject, which refuses it outright. flarepipe.com runs at p=reject. There is no reason a transactional-only domain cannot get there, and it is the policy that actually protects your customers from mail forged in your name.

Verify it from the headers

Send a test from Flarepipe > Settings with the Send Test Email tool to a Gmail address you control, open the message, choose Show original, and read the three lines at the top. What you want is spf=pass, dkim=pass and dmarc=pass, with the DKIM header.i showing your domain.

If spf fails, check that you have one SPF record, that it contains the Cloudflare include, and that it still ends in ~all. If dkim fails, the domain has not finished onboarding in Email Sending or the _domainkey record is missing or altered. If both pass and dmarc still fails, the From address does not match the domain you onboarded: the sending domain in the plugin’s settings and the domain in the From header have to be the same, and a mismatch is usually a stale From address left over from an older SMTP plugin.

What the free plugin does, and what Pro adds

The free plugin never touches your DNS. It reads your account ID, sending domain and token, posts each message to Cloudflare, and keeps the last 100 results in its log. Everything above is yours to do once, by hand, and the troubleshooting guide covers the failure modes.

Flarepipe: Email Pro adds Zero-Config Authentication: with a token scoped to edit DNS, the plugin writes the SPF and DMARC records and the records Cloudflare lists as required for the zone, and treats “already exists” as success so re-running it is safe. The records it writes are the ones described here, and the headers are still the place to confirm they work.