Updated 8 hours ago
SPF is a public declaration: "These servers speak for me. Everyone else is lying."
You publish a DNS record listing every IP address and service authorized to send email as your domain. When mail arrives claiming to be from you, receiving servers check your SPF record. If the sending server isn't on the list, the message fails authentication.
The concept is simple. The implementation has teeth.
Inventory Everything First
Before touching DNS, list every system that sends email using your domain:
- Your mail server (or Google Workspace, Office 365)
- Marketing platforms (Mailchimp, SendGrid, Constant Contact)
- CRM systems (Salesforce, HubSpot)
- Support tickets (Zendesk, Freshdesk)
- Monitoring alerts
- Web application notifications
- Transactional email services
Miss one, and that service's emails start failing. This is the step most people rush through and later regret.
For each service, find either:
- The IP addresses they send from
- Their SPF include string (most SaaS providers publish one)
Check if you already have an SPF record:
If one exists, you'll modify it. Never create a second SPF record—DNS allows only one per domain.
Build the Record
Every SPF record starts the same way:
Then you add mechanisms that authorize senders.
Your own mail server:
This authorizes whatever servers your MX records point to. Or specify IPs directly:
Cloud email providers:
Google Workspace:
Office 365:
Third-party services:
| Service | Include String |
|---|---|
| Mailchimp | include:servers.mcsv.net |
| SendGrid | include:sendgrid.net |
| Mailgun | include:mailgun.org |
| Salesforce | include:_spf.salesforce.com |
Combine them:
End with a policy:
~all(softfail): Unauthorized servers are flagged but mail still delivers. Use during testing.-all(fail): Unauthorized servers are rejected. Use in production.
Never use +all. It authorizes everyone and defeats the entire purpose.
The 10-Lookup Limit
SPF allows a maximum of 10 DNS lookups. Exceed this and SPF returns "permerror"—authentication fails entirely.
Mechanisms that cost lookups:
mx— 1 lookupa— 1 lookupinclude— 1 lookup, plus whatever that record containsexists— 1 lookup
Mechanisms that are free:
ip4andip6— no lookupsall— no lookups
This limit made sense in 2006. Today, with companies using a dozen SaaS tools that all send email, it's a constant headache.
When you hit the limit:
- Replace
includestatements with raw IP ranges where services publish them - Consolidate email services (do you really need four marketing platforms?)
- Use SPF flattening tools that resolve includes to IPs automatically
Validate Before Publishing
Use these tools to check your record before it goes live:
- MXToolbox SPF Record Checker
- dmarcian SPF Surveyor
- EasyDMARC SPF Checker
They verify syntax, count DNS lookups, and show exactly which IPs your record authorizes.
Publish the Record
Add a TXT record to your DNS:
| Field | Value |
|---|---|
| Type | TXT |
| Name | @ (root domain) |
| Value | v=spf1 mx include:_spf.google.com ~all |
| TTL | 3600 |
Subdomains need separate records. If you send mail from newsletter.yourdomain.com, it needs its own SPF:
Subdomains don't inherit the root domain's SPF.
Wait for Propagation
DNS changes take time to spread globally:
- Minimum: 5-10 minutes
- Typical: 1-4 hours
- Maximum: 24-48 hours
Verify propagation:
Test It
Send email from your authorized sources to:
check-auth@verifier.port25.com- Your own Gmail or Outlook account
Check the headers in received messages:
"pass" means SPF worked. "fail" or "softfail" means the sending server wasn't authorized.
Monitor with DMARC
Even before enforcing DMARC, set it up in monitoring mode:
You'll receive reports showing:
- Which sources pass SPF
- Which sources fail SPF
- Potential spoofing attempts
These reports reveal the services you forgot to authorize.
Tighten the Policy
Once DMARC reports confirm all legitimate sources pass:
The -all policy means unauthorized senders get rejected outright.
Common Mistakes
Multiple SPF records:
Two TXT records starting with v=spf1 causes permerror. Combine everything into one record.
Forgetting a service:
That marketing platform you onboarded six months ago? Its emails are now failing. This is why the inventory step matters.
Not updating after migrations:
Switched from Mailchimp to Klaviyo? Update SPF or the new platform's emails fail.
Exceeding 10 lookups:
Your record worked fine until you added one more include. Now everything fails with permerror.
Maintenance
Quarterly: Review DMARC reports. Check for new services that need authorization.
When adding services: Update SPF immediately. Don't wait for complaints.
Document your record: Note what each mechanism authorizes and when it was added. Future-you will appreciate this.
Frequently Asked Questions About SPF Records
Was this page helpful?