How to set up or fix your SPF record
SPF (Sender Policy Framework) is a DNS TXT record that lists the servers allowed to send email for your domain. Receiving mail servers look it up to decide whether to trust a message. Gmail and Yahoo require SPF or DKIM from every sender, and SPF, DKIM and DMARC from bulk senders. Gmail draws that line at 5,000 messages a day to personal Gmail accounts; Yahoo does not publish a number. Outlook.com requires all three from senders of more than 5,000 messages a day.
What a correct record looks like
One TXT record on the domain itself (the host is @, or blank, at most DNS providers). It starts with v=spf1, names each service that sends mail as you, and ends with an all rule:
v=spf1 include:_spf.google.com ~all
| If you send through | Add |
|---|---|
| Google Workspace | include:_spf.google.com |
| Microsoft 365 | include:spf.protection.outlook.com |
| Anything else (newsletters, CRM, invoicing, help desk, your website's contact form) | The value on that service's domain authentication screen |
Many marketing and transactional platforms need nothing added to this record. They send from their own bounce domain (Mailchimp) or from a subdomain of yours that you point at them with a CNAME (SendGrid), and ask you to set up DKIM. Use what the provider's own setup screen gives you, not a value copied from a forum post.
End the record with ~all (soft fail: mail from unlisted servers is treated as suspicious) or -all (fail: it should be rejected). Google and M3AAWG, the industry anti-abuse group, recommend ~all; Microsoft recommends -all once DKIM and DMARC are in place. DMARC counts both as an SPF failure, but some receivers reject on -all before they check DKIM or DMARC, which can block forwarded mail that would otherwise pass.
Fix the common mistakes
- Two SPF records. A domain may have only one TXT record starting
v=spf1. With two, SPF returns an error for every message, so none of it passes SPF. Merge them into one record with all the includes. - More than 10 DNS lookups. Each
include,a,mx,ptr,existsandredirectcounts toward a limit of 10, and so do the ones inside the records you include. Past 10, SPF returns an error and fails. Remove services you no longer use, dropaandmxif those servers do not send mail, and never useptr. +all, a bareall, or?all.+all(andallwith no qualifier, which means the same) authorizes every server on the internet to send as you.?allsays nothing either way. Use~allor-all.- An include that points nowhere. If an
include:names a domain that has no SPF record, often a service that changed its address or that you stopped using, the whole record errors. Remove it or replace it with the provider's current value. - A sending service missing. Mail from it fails SPF. Your DMARC reports will show it; add its include or set up DKIM for it.
- The record on the wrong name. SPF is checked on the domain in the hidden envelope sender (the return-path), which is usually your domain itself but can be a bounce subdomain a provider asks you to set up. Publish it wherever your providers' setup screens say.
wwwneeds one only if mail is sent from it.
Where to add it
- Find your DNS host: wherever your domain's nameservers point. It is often the registrar or Cloudflare, not your web host.
- Edit the existing TXT record that starts
v=spf1, or add one if there is none. Host:@. Value: the full record. - Save, wait a few minutes, and check it:
dig +short TXT example.com, or Google's Admin Toolbox Dig in a browser.
SPF is only one part
SPF checks the hidden envelope sender, not the From address people see, and it breaks when mail is forwarded. DKIM usually survives forwarding, and DMARC ties both to the visible From address. Set up all three.
Check it worked
Run WEBCHKR again. The SPF Record check reads the record, counts the DNS lookups it needs, following nested includes, and lists the services it authorizes, so you can confirm none is missing. It fails on no record, more than one record, more than 10 lookups, +all, or an include with no SPF record behind it, and it notes when you are at 9 or 10 lookups and close to the limit.