SPF (Sender Policy Framework)
SPF is an email authentication protocol that specifies which mail servers are authorized to send email on behalf of your domain.
How SPF Works
The Problem
Without SPF, anyone can send email claiming to be from your domain. There's no way for receiving servers to know if the sender is legitimate.
The Solution
SPF allows you to publish a list of authorized senders in DNS:
example.com. TXT "v=spf1 include:_spf.google.com -all"When a receiving server gets an email "from" your domain:
- It looks up your SPF record in DNS
- It checks if the sending server is authorized
- It passes or fails the email based on your policy
SPF Record Syntax
An SPF record consists of:
v=spf1 [mechanisms] [all-policy]Version Tag
Always starts with v=spf1 (required).
Mechanisms
Mechanisms define who is authorized to send:
| Mechanism | Description | Example |
|---|---|---|
ip4: | IPv4 address or range | ip4:192.0.2.0/24 |
ip6: | IPv6 address or range | ip6:2001:db8::/32 |
a: | A record of domain | a:mail.example.com |
mx: | MX records of domain | mx or mx:example.com |
include: | Include another domain's SPF | include:_spf.google.com |
exists: | Check if domain exists | exists:%{i}._spf.example.com |
redirect= | Redirect to another domain | redirect=_spf.example.com |
Qualifiers
Mechanisms can have qualifiers:
| Qualifier | Meaning | Result |
|---|---|---|
+ | Pass (default) | Authorized |
- | Fail | Not authorized |
~ | SoftFail | Probably not authorized |
? | Neutral | No opinion |
All Policy
The all mechanism at the end defines the default policy:
| Policy | Meaning | Recommendation |
|---|---|---|
-all | Hard fail - reject unauthorized | Recommended for production |
~all | Soft fail - accept but mark | Good for testing |
?all | Neutral - no policy | Not recommended |
+all | Pass all - allow anyone | Never use this |
Example Records
Basic - Google Workspace Only
v=spf1 include:_spf.google.com -allMultiple Services
v=spf1 include:_spf.google.com include:sendgrid.net include:mail.zendesk.com -allOwn Mail Server + Services
v=spf1 mx ip4:203.0.113.0/24 include:_spf.google.com -allThe Include Tree
When SPF uses include:, the included domain's SPF is evaluated recursively. This creates an "include tree":
example.com
└── include:_spf.google.com
├── include:_netblocks.google.com
│ └── ip4:35.190.247.0/24 (and more)
├── include:_netblocks2.google.com
│ └── ip4:64.18.0.0/20 (and more)
└── include:_netblocks3.google.com
└── ip4:66.102.0.0/20 (and more)MailShield visualizes this tree to help you understand your SPF configuration.
DNS Lookup Limit
Critical: SPF is limited to 10 DNS lookups per evaluation (RFC 7208).
These mechanisms count as DNS lookups:
include:a:mx:exists:redirect=
These do NOT count:
ip4:andip6:all
Avoiding Lookup Limit
- Use IP ranges instead of hostnames when possible
- Flatten SPF - replace includes with IP ranges
- Remove unused includes - audit regularly
- Use subdomains for different services
Common Issues
Too Many DNS Lookups
Problem: Record exceeds 10 DNS lookup limit.
Symptoms:
- SPF permanently fails
- Email delivery issues
Solutions:
- Flatten includes to IP ranges
- Remove unused mechanisms
- Use SPF flattening services
Multiple SPF Records
Problem: More than one SPF TXT record exists.
Symptoms:
- Unpredictable authentication results
Solution:
- Merge into a single record
- Delete duplicate records
Syntax Errors
Problem: Invalid SPF syntax.
Common mistakes:
- Missing
v=spf1 - Typos in mechanism names
- Invalid IP ranges
Solution:
- Validate with MailShield or other tools
No All Mechanism
Problem: Record doesn't end with all.
Impact:
- Neutral result for unauthorized senders
- Reduced protection
Solution:
- Add
-allor~allat the end
SPF and Email Forwarding
SPF can break when email is forwarded because:
- Original sender passes SPF
- Email is forwarded by another server
- Forwarding server's IP isn't in sender's SPF
- SPF fails at final destination
Solutions:
- Rely on DKIM (survives forwarding)
- Use SRS (Sender Rewriting Scheme) on forwarding servers
- Set DMARC to use relaxed SPF alignment
SPF Alignment for DMARC
For DMARC, SPF must "align" with the From header:
Relaxed alignment (default):
- Envelope domain can be a subdomain of From header domain
mail.example.comaligns withexample.com
Strict alignment:
- Domains must match exactly
Best Practices
Do
✅ Use -all for hard fail in production
✅ Test with ~all before enforcing
✅ Monitor DNS lookup count
✅ Include all legitimate sending services
✅ Audit and remove unused includes regularly
Don't
❌ Use +all (allows everyone)
❌ Use deprecated ptr mechanism
❌ Exceed 10 DNS lookups
❌ Have multiple SPF records
❌ Forget about third-party senders \
Testing Your SPF
With MailShield
- Add your domain to MailShield
- View the SPF check results
- See the include tree visualization
- Check DNS lookup count
Manual Testing
# Look up SPF record
dig +short TXT example.com | grep spf
# Check from command line
nslookup -type=txt example.comCommon Provider SPF Includes
| Provider | Include |
|---|---|
| Google Workspace | include:_spf.google.com |
| Microsoft 365 | include:spf.protection.outlook.com |
| Amazon SES | include:amazonses.com |
| SendGrid | include:sendgrid.net |
| Mailchimp | include:servers.mcsv.net |
| Postmark | include:spf.mtasv.net |
| Zendesk | include:mail.zendesk.com |
| Salesforce | include:_spf.salesforce.com |