SPF Record Syntax Explained: A Complete Reference
What Is an SPF Record?
An SPF (Sender Policy Framework) record is a DNS TXT entry that tells the world which mail servers are allowed to send email on behalf of your domain. When a receiving server gets an email claiming to come from your domain, it looks up your SPF record and checks whether the sending IP is authorized.
Without SPF, anyone can send email pretending to be you. With a properly configured SPF record, spoofed messages get flagged or rejected before they reach the inbox.
SPF Record Structure
Every SPF record starts with v=spf1 and ends with an all-mechanism. Between those bookends, you list your authorized senders using mechanisms and modifiers.
v=spf1 ip4:203.0.113.0/24 include:_spf.google.com -all
Let's break down each component.
Qualifiers
Every mechanism can be prefixed with a qualifier that determines what happens when it matches:
| Qualifier | Meaning | Result |
|---|---|---|
+ (default) |
Pass | Sender is authorized |
- |
Fail | Sender is NOT authorized |
~ |
SoftFail | Sender is probably not authorized |
? |
Neutral | No assertion either way |
If you omit the qualifier, + (pass) is assumed. So include:example.com means +include:example.com.
Core Mechanisms
ip4 and ip6
Authorize specific IP addresses or CIDR ranges.
v=spf1 ip4:203.0.113.5 ip4:198.51.100.0/24 ip6:2001:db8::/32 -all
Use these for mail servers you control directly. Always prefer CIDR notation for ranges rather than listing individual IPs.
a
Authorizes the IP addresses found in the domain's A (or AAAA) record.
v=spf1 a -all
This says "whatever IP my domain points to is allowed to send mail." You can also reference another domain: a:mail.example.com.
mx
Authorizes the IPs of the domain's MX (mail exchange) servers.
v=spf1 mx -all
Useful when your inbound mail servers also handle outbound. Like a, you can point it at another domain: mx:example.com.
include
Pulls in the SPF record of another domain and evaluates it. This is how you authorize third-party email services.
v=spf1 include:_spf.google.com include:sendgrid.net -all
Each include counts as one DNS lookup. SPF allows a maximum of 10 DNS lookups per evaluation — exceeding this limit causes a permanent error (permerror).
all
The catch-all mechanism. It always matches, so it should be the last item in your record.
-all— Hard fail: reject unauthorized senders (recommended for enforced domains)~all— Soft fail: accept but mark as suspicious (good while testing)?all— Neutral: no opinion (rarely useful)+all— Pass everything: never use this — it defeats the purpose of SPF
Less Common Mechanisms
exists
Checks whether an A record exists for a given domain. Used for advanced macro-based policies.
v=spf1 exists:%{i}._spf.example.com -all
This performs a lookup for each sending IP against your custom DNS zone, enabling per-IP authorization without burning through lookup limits.
ptr (Deprecated)
Checks if the sending IP reverse-resolves to the domain. Officially deprecated in RFC 7208 because it's slow, unreliable, and puts load on DNS. Don't use it.
Modifiers
redirect
Points to another domain's SPF record entirely, replacing the current one. Unlike include, redirect is evaluated only if no other mechanism matches.
v=spf1 redirect=_spf.example.com
exp
Provides a custom explanation message when SPF fails. The value must point to a TXT record containing the message.
v=spf1 -all exp=spfexplain.example.com
Where spfexplain.example.com has a TXT record like: "Mail from example.com must come from authorized servers. See https://example.com/spf"
The 10-Lookup Limit
SPF evaluations are limited to 10 DNS lookups. Each include, a, mx, exists, and redirect counts as one. Nested includes count against your total too.
What counts:
include:example.com→ 1 lookup (plus any lookups inside that record)aora:example.com→ 1 lookupmxormx:example.com→ 1 lookupredirect=example.com→ 1 lookupexists:example.com→ 1 lookup
What doesn't count:
ip4:andip6:— no DNS lookup neededall— no lookup needed
When you exceed 10 lookups, the SPF check returns permerror and most receivers treat your mail as unauthenticated. This is the single most common SPF misconfiguration.
How to Fix It
- Audit your includes: Some services nest multiple levels of includes. Use an SPF investigator tool to see the full chain.
- Flatten: Replace
includemechanisms with the actual IP ranges they resolve to. This eliminates DNS lookups but requires monitoring for changes. - Remove unused services: If you stopped using a mail provider, remove their include.
Common SPF Patterns
Google Workspace only
v=spf1 include:_spf.google.com ~all
Microsoft 365 only
v=spf1 include:spf.protection.outlook.com -all
Multiple services (typical SaaS business)
v=spf1 include:_spf.google.com include:sendgrid.net include:mail.zendesk.com -all
On-premise server + cloud
v=spf1 ip4:203.0.113.10 include:_spf.google.com -all
Best Practices
- Start with
~all, move to-all: While testing, use softfail. Once you've confirmed all legitimate sources are listed, switch to hardfail. - Keep it under 10 lookups: Monitor your lookup count. Use SPF flattening if you're close to the limit.
- Don't use
+all: This authorizes the entire internet to send as you. There is never a good reason to use it. - One SPF record per domain: Multiple SPF TXT records cause evaluation failure. Merge them into one.
- Monitor changes: Third-party services update their SPF includes. Use automated monitoring to catch changes that could break your record.
- Use DMARC alongside SPF: SPF alone doesn't prevent display-name spoofing. DMARC ties SPF to the From header via alignment.
Testing Your SPF Record
After publishing your SPF record, validate it:
- Run an SPF lookup to confirm the record is published and syntactically correct
- Check that your lookup count is under 10
- Send a test email and inspect the
Authentication-Resultsheader forspf=pass - Monitor your DMARC reports for SPF failures from legitimate sources
Summary
SPF is your first line of defense in email authentication. A well-crafted SPF record authorizes your legitimate senders and tells the world to reject everything else. Combined with DKIM and DMARC, it forms the foundation of a secure email infrastructure.
The key takeaways: use specific mechanisms (ip4, include) rather than broad ones (a, mx), stay under the 10-lookup limit, and always end with -all once you're confident in your configuration.