Introduction
SPF (Sender Policy Framework) is a DNS record that specifies which IP addresses are authorized to send email for a domain. When the hosting server's IP address is not included in the SPF record, receiving mail servers fail the SPF check and may mark emails as spam or reject them entirely. This is common after migrating to a new hosting provider or adding third-party email services.
Symptoms
- Email headers show
SPF: FailorSPF: Softfail - Emails land in recipient spam folders
- Receiving mail server returns
550 5.7.23 SPF check failed - Email testing tools (MXToolbox, Mail-Tester) show SPF failure
- Error message:
Received-SPF: fail (google.com: domain of example.com does not designate x.x.x.x as permitted sender)
Common Causes
- SPF record only includes the old hosting provider's IP address
- Third-party email service (SendGrid, Mailchimp) not added to SPF record
- SPF record using
includemechanism that does not cover the current sending IP - Multiple SPF records (only the first one is evaluated)
- SPF record syntax error causing the entire record to be ignored
Step-by-Step Fix
- 1.Check the current SPF record: See what IPs are currently authorized.
- 2.```bash
- 3.dig TXT example.com +short | grep "v=spf1"
- 4.# Example output: "v=spf1 include:_spf.old-hosting.com ~all"
- 5.
` - 6.Identify the actual sending IP address: Find the IP that emails are sent from.
- 7.```bash
- 8.# Check the mail server's outgoing IP
- 9.curl -s ifconfig.me
- 10.# Or check email headers from a sent message
- 11.# Look for the last Received: header with the sending IP
- 12.
` - 13.Update the SPF record to include the correct IP: Fix the DNS record.
- 14.```dns
- 15.# WRONG: Missing current hosting IP
- 16."v=spf1 include:_spf.old-hosting.com ~all"
# CORRECT: Include current hosting provider and third-party services "v=spf1 ip4:123.45.67.89 include:_spf.new-hosting.com include:sendgrid.net ~all" ```
- 1.Verify there is only one SPF record: Remove duplicates.
- 2.```bash
- 3.dig TXT example.com +short | grep "v=spf1" | wc -l
- 4.# Should return 1 - if more, merge into a single record
- 5.
` - 6.Test the updated SPF record: Verify the fix works.
- 7.```bash
- 8.# Check SPF record validity
- 9.dig TXT example.com +short | grep "v=spf1"
- 10.# Test with mxtoolbox
- 11.# https://mxtoolbox.com/spf.aspx
- 12.
`
Prevention
- Review and update SPF records whenever changing hosting providers or adding email services
- Keep SPF records under 10 DNS lookups (SPF specification limit)
- Use
~all(softfail) instead of-all(hardfail) during testing - Monitor email deliverability metrics and SPF pass rates
- Include all third-party email services in the SPF record
- Test SPF records after every DNS change using online SPF validators