What is SPF? How it works, a good record, and how to check yours
SPF (Sender Policy Framework) is a DNS TXT record on your domain that lists which mail servers are allowed to send email for it. Receiving servers compare the sending server against this list and treat mail from anywhere else as suspicious.
A typical record for Google Workspace looks like v=spf1 include:_spf.google.com ~all. You can have only one SPF record per domain, and it may trigger at most 10 DNS lookups.
How SPF works
SPF checks the envelope sender (the "Return-Path"), not the From address people see. That is why SPF alone does not stop spoofing; DMARC ties it to the visible From address.
- A server connects to the receiver and says the mail is from
bounce@example.com. - The receiver looks up the TXT record starting with
v=spf1atexample.com. - It walks through the mechanisms left to right (
ip4,include,mxand so on) until one matches the sending server's IP address. - If nothing matches, the final
alldecides:-allfail,~allsoft fail,?allneutral. - The result (pass, fail, softfail, neutral, permerror) feeds into DMARC and spam filtering.
Example of a good SPF record
A domain that uses Google Workspace for mailboxes and SendGrid for newsletters, published as one TXT record at the root (@):
v=spf1 include:_spf.google.com include:sendgrid.net ~all
| Part | Meaning |
|---|---|
v=spf1 | Marks this TXT record as SPF. Must come first. |
include: | Also allow the servers listed in another domain's SPF record. Each include costs at least one DNS lookup. |
a | Allow the IP addresses in the domain's A/AAAA records. One lookup. |
mx | Allow your incoming mail servers to send too. One lookup plus one per MX host. |
ip4: / ip6: | Allow a specific IP address or range, for example ip4:192.0.2.0/24. No lookup. |
exists: | Advanced: pass if a constructed name resolves. One lookup. Rarely needed. |
redirect= | Use another domain's SPF record instead of this one. Only used when there is no all. |
~all | Soft fail everything not listed: accept but mark as suspicious. A safe default with DMARC. |
-all | Hard fail everything not listed. Strongest, but only use it once you are sure every sender is listed. |
| 10-lookup limit | include, a, mx, exists, redirect and nested includes all count. More than 10 makes SPF fail with a permanent error. |
Common SPF mistakes
- More than one SPF record
- Two TXT records starting with
v=spf1make SPF fail for every message. Merge them into one record. - Too many DNS lookups
- Every new email tool adds an
include. Past 10 lookups, SPF breaks. Remove services you no longer use, or replace includes withip4ranges where the provider allows it. - Using +all or ?all
+alllets anyone on the internet send as you.?allgives no protection. End with~allor-all.- No all at the end
- Without an
allmechanism, unlisted servers get a neutral result, which protects nothing. - Using the deprecated ptr mechanism
ptris slow, unreliable and discouraged by the SPF standard. Some receivers ignore it. Replace it withip4/ip6or aninclude.- Forgetting a sending service
- Invoices from your billing tool or tickets from your help desk fail SPF if their include is missing. List every service that sends as your domain.
- Publishing SPF as the old SPF record type
- The separate DNS "SPF" record type is obsolete. Publish SPF as a TXT record.
How to fix or create your SPF record
- List every service that sends email as your domain: mailbox provider, newsletter, CRM, help desk, billing, website forms.
- Find each provider's SPF include in their help docs (for example
include:_spf.google.comorinclude:spf.protection.outlook.com). - Combine them into one record:
v=spf1, then the includes and anyip4ranges, then~all. - Replace your existing SPF TXT record at the root (host
@) with the new one. Do not add a second one. - Run the check again to confirm a single record under 10 lookups.
SPF FAQ
Can I have two SPF records?
No. A domain must have exactly one TXT record starting with v=spf1. If there are two, receivers return a permanent error and SPF fails for all your mail. Merge the mechanisms into one record.
Should I use ~all or -all?
Use ~all (soft fail) while you are still finding all your senders, and with DMARC in place it gives good protection. Switch to -all (hard fail) once you are confident every legitimate sender is listed. Both are far better than ?all or +all.
What is the SPF 10-lookup limit?
SPF evaluation may trigger at most 10 DNS lookups. include, a, mx, exists and redirect each count, including the ones inside included records. If the total goes over 10, SPF returns a permanent error and fails.
Does SPF stop people from spoofing my domain?
Not on its own. SPF checks the hidden envelope sender, not the From address people see, so a spoofer can pass SPF with their own domain. DMARC closes that gap by requiring the SPF domain to match the visible From domain.
Where do I add an SPF record?
At your DNS host, add a TXT record with host or name @ (the root of your domain) and a value like v=spf1 include:_spf.google.com ~all. If an SPF record already exists, edit it instead of adding a new one.
Do subdomains inherit my SPF record?
No. SPF applies only to the exact domain it is published on. If you send from news.example.com, that subdomain needs its own SPF record.
What SPF include does Microsoft 365 use?
Microsoft 365 uses include:spf.protection.outlook.com. A Microsoft 365 only domain would publish v=spf1 include:spf.protection.outlook.com -all.