An SPF record is a single line of text in your DNS that lists the servers allowed to send email for your domain. Get it right and receiving servers can tell your real mail from forgeries. Get it wrong, with two records, a typo or one include too many, and your own mail fails authentication. This guide explains how SPF works, what each part of the syntax means, and how to write a record you can copy into your DNS today.
Key takeaways
- An SPF record is a single DNS TXT record that lists the servers allowed to send email for your domain.
- A domain must have exactly one SPF record, because two or more cause a permanent error that fails SPF for every message.
- SPF allows at most 10 DNS lookups, counting nested includes, and going over the limit also causes a permanent error.
- SPF checks the envelope sender rather than the visible From address, so you also need DMARC and DKIM to stop spoofing.
What SPF actually checks
SPF (Sender Policy Framework, defined in RFC 7208) answers one question: is this IP address allowed to send mail for this domain?
The important detail is which domain. SPF checks the envelope sender, the address in the SMTP MAIL FROM command, which ends up in the Return-Path header. It does not check the From: address people see in their inbox. When you send through a newsletter platform, the envelope sender is often the platform's own bounce domain, so SPF passes for their domain, not yours.
That gap is why SPF alone doesn't stop spoofing. DMARC closes it by requiring the SPF domain (or the DKIM domain) to match the visible From: domain. See DMARC explained for how alignment works.
When a message arrives, the receiving server:
- Takes the domain from the envelope sender (for example
bounce.example.com). - Looks up the TXT records on that domain and finds the one that starts with
v=spf1. - Evaluates the record left to right until a mechanism matches the connecting IP.
- Returns a result:
pass,fail,softfail,neutral,none,temperrororpermerror.
Anatomy of an SPF record
Here is a typical record for a business that uses Google Workspace and a marketing platform:
example.com. 3600 IN TXT "v=spf1 include:_spf.google.com include:servers.mcsv.net ip4:203.0.113.25 ~all"
Reading left to right:
v=spf1: the version tag. It must be first and exactly this.include:_spf.google.com: also allow any IP that Google's SPF record allows.include:servers.mcsv.net: also allow the marketing platform's servers.ip4:203.0.113.25: also allow this specific server, such as your web server sending contact-form mail.~all: anything that didn't match above is a softfail.
Mechanisms
| Mechanism | Matches when | Costs a DNS lookup? |
|---|---|---|
ip4:203.0.113.0/24 |
The sender's IPv4 address is in the range | No |
ip6:2001:db8::/32 |
The sender's IPv6 address is in the range | No |
a or a:host.example.com |
The sender's IP matches the domain's A/AAAA record | Yes |
mx or mx:example.com |
The sender's IP matches one of the domain's MX hosts | Yes |
include:domain |
The other domain's SPF record returns pass | Yes |
exists:domain |
An A record exists for the (usually macro-built) name | Yes |
ptr |
Reverse DNS of the IP matches the domain | Yes, and RFC 7208 says do not use it |
all |
Always matches. Put it last | No |
The redirect=domain modifier replaces your record with another domain's record, and it also counts as a lookup. Only the mechanisms marked "Yes" count toward the 10-lookup limit covered below.
Qualifiers
Each mechanism can have a prefix that sets the result when it matches. With no prefix, the default is + (pass).
| Qualifier | Result | Typical use |
|---|---|---|
+ |
pass | Implied, rarely written |
- |
fail | -all: reject anything not listed |
~ |
softfail | ~all: accept but treat as suspicious |
? |
neutral | ?all: no statement. Almost useless |
~all or -all?
Both are widely used. Google's Workspace setup guide recommends ~all. Microsoft's own SPF record for Exchange Online ends in -all. Once you have DMARC at enforcement, DMARC decides what happens to failing mail, so the difference matters less. A sensible approach: use ~all while you are still finding every service that sends for you, and consider -all when your DMARC reports show nothing legitimate is failing. Never use +all, which authorizes the whole internet to send as you.
Copy-ready examples
Google Workspace only:
v=spf1 include:_spf.google.com ~all
Microsoft 365 only:
v=spf1 include:spf.protection.outlook.com -all
Microsoft 365 plus a transactional email service and your web server:
v=spf1 include:spf.protection.outlook.com include:sendgrid.net ip4:198.51.100.10 -all
A domain that never sends email (parked domains, redirect-only domains):
v=spf1 -all
A subdomain used only by your ESP for bounces: most ESPs ask you to point a subdomain like em.example.com or bounce.example.com at them with a CNAME. Their SPF record then applies automatically, and your root record stays short.
Always take include values from your provider's current documentation. Vendors change their records, and copying an outdated include from an old blog post is a common source of failures.
How to add or edit your SPF record
-
Find what you already have. Look up TXT records on your domain:
dig +short TXT example.com | grep spf1On Windows:
nslookup -type=TXT example.com -
List every service that sends as your domain. Mailbox provider, newsletter tool, CRM, help desk, e-commerce platform, billing system, website forms, scanners and printers that email. Your DMARC reports are the most reliable way to find ones you forgot.
-
Merge them into one record. Edit the existing
v=spf1TXT record rather than adding a second. -
Publish at the root (
@in most DNS dashboards) as a TXT record. The old SPF DNS record type (type 99) is obsolete; use TXT. -
Test. Send a message to a Gmail account, open Show original, and confirm
SPF: PASS. Or run a free audit to validate the syntax and count lookups.
The mistakes that break SPF
Two SPF records
RFC 7208 says a domain must not have multiple SPF records. If a receiver finds two TXT records starting with v=spf1, the result is permerror, and SPF fails for all your mail. This usually happens when a new service's setup guide says "add this TXT record" and someone adds it instead of merging it.
Wrong:
example.com. TXT "v=spf1 include:_spf.google.com ~all"
example.com. TXT "v=spf1 include:sendgrid.net ~all"
Right:
example.com. TXT "v=spf1 include:_spf.google.com include:sendgrid.net ~all"
Too many DNS lookups
SPF evaluation may trigger at most 10 lookups from include, a, mx, ptr, exists and redirect, counting nested includes. Exceed it and the result is permerror. This is the most common SPF failure for growing businesses. Our guide to fixing "too many DNS lookups" shows how to count and cut them.
Too many void lookups
A lookup that returns no records (for example, an include pointing to a domain that no longer exists) is a "void lookup." RFC 7208 says implementations should limit these to two, so stale includes for services you stopped using can also cause permerror. Remove them.
Strings over 255 characters
A single TXT string can hold at most 255 characters. Longer records must be split into multiple quoted strings, which receivers join without spaces:
example.com. TXT ( "v=spf1 include:_spf.google.com include:spf.protection.outlook.com "
"include:sendgrid.net ip4:198.51.100.10 -all" )
Note the space at the end of the first string. Without it, the two strings join into outlook.cominclude: and the record breaks. Many DNS dashboards split long values for you.
Syntax typos
Common ones: v=spf1 written as v=spf 1 or v=SPF1 with stray characters, include: _spf.google.com with a space after the colon, ip4: holding an IPv6 address, smart quotes pasted from a document, and anything placed after all (it is ignored).
Forgetting subdomains
SPF is not inherited. A record on example.com does not cover mail.example.com. If a service sends with an envelope sender on a subdomain, that subdomain needs its own record.
Expecting SPF to survive forwarding
When a message is forwarded, the forwarding server's IP isn't in your SPF record, so SPF often fails at the final destination. That's normal. DKIM signatures usually survive forwarding, which is one reason you need DKIM as well.
Frequently asked questions
Can I have more than one SPF record?
No. A domain must have exactly one TXT record starting with v=spf1. Two or more cause a permanent error, which fails SPF for every message. Merge all your senders into one record.
Does SPF stop people from spoofing my From: address?
Not on its own. SPF checks the envelope sender, which a spoofer can set to their own domain while showing your address in the From: line. DMARC, which requires alignment between the From: domain and SPF or DKIM, is what blocks that.
Where do I put the SPF record?
In your domain's DNS zone, as a TXT record on the root (often shown as @). Edit it wherever your nameservers are hosted: your registrar, Cloudflare, or your hosting provider. Changes usually take effect within the record's TTL.
Should I include my MX servers with the mx mechanism?
Only if those servers actually send outbound mail. With hosted email like Google Workspace or Microsoft 365, the provider's include already covers outbound servers, and adding mx just wastes a DNS lookup.
What to do next
Look up your current SPF record, compare it with the list of services that really send as your domain, and merge everything into one clean record. Then check the lookup count, because that limit is usually the next thing that breaks. If you would rather not count by hand, a free audit parses your record and flags duplicates, syntax errors and missing DMARC in one pass.
Sources
Written by the MakeItFlow team
We build the website audit these guides are based on. Every fact is checked against the primary sources listed above . How we research and check
Check your own site in 30 seconds
Run a free audit covering speed, SEO, DNS, email authentication and security headers — and get a prioritised fix list.