esc

SPF Checker

Validate SPF DNS syntax, check a domain SPF record, parse mechanisms and count include-chain DNS lookups against the 10-lookup limit.

Examples google.com github.com cloudflare.com
SPF Record Valid TXT ~all · SoftFail
github.com
Published as a DNS TXT record · 320 characters · 1 of 1 SPF record
v=spf1 ip4:192.30.252.0/22 include:spf.protection.outlook.com include:_netblocks.google.com include:_netblocks2.google.com include:mail.zendesk.com include:_spf.salesforce.com include:servers.mcsv.net include:mktomail.com include:sendgrid.net ip4:62.253.227.114 ip4:166.78.69.169 ip4:166.78.69.170 ip4:166.78.71.131 ~all
DNS lookups
10 / 10
Mechanisms
14
Sending sources
13
10 of 10 DNS lookups
Validation
4 passed@if(data.warnCount) · 3 to review@end@if(data.failCount) · 0 failed@end
Exactly one SPF record published
A domain must publish a single v=spf1 TXT record — multiple records cause a PermError.
Pass
Starts with the v=spf1 version tag
The record opens with the correct, case-insensitive version token.
Pass
10 of 10 DNS lookups used
SPF permits at most 10 DNS-querying mechanisms before a PermError. You have 0 to spare.
Review
Enforcement is ~all (SoftFail)
Unauthorised mail is accepted but flagged. Move to -all once every legitimate sender is listed, to reject spoofed mail outright.
Review
No +all mechanism
The record does not authorise the entire internet to send mail as this domain.
Pass
No deprecated ptr mechanism
ptr is slow and discouraged by RFC 7208 — none present.
Pass
Each string under 255 characters
The record is 320 characters and fits in a single DNS TXT string.
Review
Mechanisms
14 terms
QualifierMechanismValueDNS lookup
Pass ip4 192.30.252.0/22
Pass include spf.protection.outlook.com +1
Pass include _netblocks.google.com +1
Pass include _netblocks2.google.com +1
Pass include mail.zendesk.com +1
Pass include _spf.salesforce.com +1
Pass include servers.mcsv.net +1
Pass include mktomail.com +1
Pass include sendgrid.net +1
Pass ip4 62.253.227.114
Pass ip4 166.78.69.169
Pass ip4 166.78.69.170
Pass ip4 166.78.71.131
SoftFail all ~all
DNS lookup chain
10 / 10 lookups
@if(node.kind === 'include')github.com v=spf1@elseif(node.kind === 'all')github.com v=spf1@elseif(node.kind === 'root')github.com v=spf1@elsegithub.com v=spf1@endif cost
├─ @if(node.kind === 'include')ip4:192.30.252.0/22@elseif(node.kind === 'all')ip4:192.30.252.0/22@elseif(node.kind === 'root')ip4:192.30.252.0/22@elseip4:192.30.252.0/22@endif 0
├─ @if(node.kind === 'include')include:spf.protection.outlook.com@elseif(node.kind === 'all')include:spf.protection.outlook.com@elseif(node.kind === 'root')include:spf.protection.outlook.com@elseinclude:spf.protection.outlook.com@endif +1
│  ├─ @if(node.kind === 'include')ip4:40.92.0.0/15@elseif(node.kind === 'all')ip4:40.92.0.0/15@elseif(node.kind === 'root')ip4:40.92.0.0/15@elseip4:40.92.0.0/15@endif 0
│  ├─ @if(node.kind === 'include')ip4:40.107.0.0/16@elseif(node.kind === 'all')ip4:40.107.0.0/16@elseif(node.kind === 'root')ip4:40.107.0.0/16@elseip4:40.107.0.0/16@endif 0
│  ├─ @if(node.kind === 'include')ip4:52.100.0.0/15@elseif(node.kind === 'all')ip4:52.100.0.0/15@elseif(node.kind === 'root')ip4:52.100.0.0/15@elseip4:52.100.0.0/15@endif 0
│  ├─ @if(node.kind === 'include')ip4:52.102.0.0/16@elseif(node.kind === 'all')ip4:52.102.0.0/16@elseif(node.kind === 'root')ip4:52.102.0.0/16@elseip4:52.102.0.0/16@endif 0
│  ├─ @if(node.kind === 'include')ip4:52.103.0.0/17@elseif(node.kind === 'all')ip4:52.103.0.0/17@elseif(node.kind === 'root')ip4:52.103.0.0/17@elseip4:52.103.0.0/17@endif 0
│  ├─ @if(node.kind === 'include')ip4:104.47.0.0/17@elseif(node.kind === 'all')ip4:104.47.0.0/17@elseif(node.kind === 'root')ip4:104.47.0.0/17@elseip4:104.47.0.0/17@endif 0
│  ├─ @if(node.kind === 'include')ip6:2a01:111:f400::/48@elseif(node.kind === 'all')ip6:2a01:111:f400::/48@elseif(node.kind === 'root')ip6:2a01:111:f400::/48@elseip6:2a01:111:f400::/48@endif 0
│  ├─ @if(node.kind === 'include')ip6:2a01:111:f403::/49@elseif(node.kind === 'all')ip6:2a01:111:f403::/49@elseif(node.kind === 'root')ip6:2a01:111:f403::/49@elseip6:2a01:111:f403::/49@endif 0
│  ├─ @if(node.kind === 'include')ip6:2a01:111:f403:8000::/51@elseif(node.kind === 'all')ip6:2a01:111:f403:8000::/51@elseif(node.kind === 'root')ip6:2a01:111:f403:8000::/51@elseip6:2a01:111:f403:8000::/51@endif 0
│  ├─ @if(node.kind === 'include')ip6:2a01:111:f403:c000::/51@elseif(node.kind === 'all')ip6:2a01:111:f403:c000::/51@elseif(node.kind === 'root')ip6:2a01:111:f403:c000::/51@elseip6:2a01:111:f403:c000::/51@endif 0
│  ├─ @if(node.kind === 'include')ip6:2a01:111:f403:f000::/52@elseif(node.kind === 'all')ip6:2a01:111:f403:f000::/52@elseif(node.kind === 'root')ip6:2a01:111:f403:f000::/52@elseip6:2a01:111:f403:f000::/52@endif 0
│  └─ @if(node.kind === 'include')-all@elseif(node.kind === 'all')-all@elseif(node.kind === 'root')-all@else-all@endif 0
├─ @if(node.kind === 'include')include:_netblocks.google.com@elseif(node.kind === 'all')include:_netblocks.google.com@elseif(node.kind === 'root')include:_netblocks.google.com@elseinclude:_netblocks.google.com@endif +1
│  ├─ @if(node.kind === 'include')ip4:74.125.0.0/16@elseif(node.kind === 'all')ip4:74.125.0.0/16@elseif(node.kind === 'root')ip4:74.125.0.0/16@elseip4:74.125.0.0/16@endif 0
│  ├─ @if(node.kind === 'include')ip4:209.85.128.0/17@elseif(node.kind === 'all')ip4:209.85.128.0/17@elseif(node.kind === 'root')ip4:209.85.128.0/17@elseip4:209.85.128.0/17@endif 0
│  └─ @if(node.kind === 'include')~all@elseif(node.kind === 'all')~all@elseif(node.kind === 'root')~all@else~all@endif 0
├─ @if(node.kind === 'include')include:_netblocks2.google.com@elseif(node.kind === 'all')include:_netblocks2.google.com@elseif(node.kind === 'root')include:_netblocks2.google.com@elseinclude:_netblocks2.google.com@endif +1
│  ├─ @if(node.kind === 'include')ip6:2001:4860:4000::/36@elseif(node.kind === 'all')ip6:2001:4860:4000::/36@elseif(node.kind === 'root')ip6:2001:4860:4000::/36@elseip6:2001:4860:4000::/36@endif 0
│  ├─ @if(node.kind === 'include')ip6:2404:6800:4000::/36@elseif(node.kind === 'all')ip6:2404:6800:4000::/36@elseif(node.kind === 'root')ip6:2404:6800:4000::/36@elseip6:2404:6800:4000::/36@endif 0
│  ├─ @if(node.kind === 'include')ip6:2607:f8b0:4000::/36@elseif(node.kind === 'all')ip6:2607:f8b0:4000::/36@elseif(node.kind === 'root')ip6:2607:f8b0:4000::/36@elseip6:2607:f8b0:4000::/36@endif 0
│  ├─ @if(node.kind === 'include')ip6:2800:3f0:4000::/36@elseif(node.kind === 'all')ip6:2800:3f0:4000::/36@elseif(node.kind === 'root')ip6:2800:3f0:4000::/36@elseip6:2800:3f0:4000::/36@endif 0
│  ├─ @if(node.kind === 'include')ip6:2a00:1450:4000::/36@elseif(node.kind === 'all')ip6:2a00:1450:4000::/36@elseif(node.kind === 'root')ip6:2a00:1450:4000::/36@elseip6:2a00:1450:4000::/36@endif 0
│  ├─ @if(node.kind === 'include')ip6:2c0f:fb50:4000::/36@elseif(node.kind === 'all')ip6:2c0f:fb50:4000::/36@elseif(node.kind === 'root')ip6:2c0f:fb50:4000::/36@elseip6:2c0f:fb50:4000::/36@endif 0
│  └─ @if(node.kind === 'include')~all@elseif(node.kind === 'all')~all@elseif(node.kind === 'root')~all@else~all@endif 0
├─ @if(node.kind === 'include')include:mail.zendesk.com@elseif(node.kind === 'all')include:mail.zendesk.com@elseif(node.kind === 'root')include:mail.zendesk.com@elseinclude:mail.zendesk.com@endif +1
│  ├─ @if(node.kind === 'include')ip4:103.151.192.0/23@elseif(node.kind === 'all')ip4:103.151.192.0/23@elseif(node.kind === 'root')ip4:103.151.192.0/23@elseip4:103.151.192.0/23@endif 0
│  ├─ @if(node.kind === 'include')ip4:185.12.80.0/22@elseif(node.kind === 'all')ip4:185.12.80.0/22@elseif(node.kind === 'root')ip4:185.12.80.0/22@elseip4:185.12.80.0/22@endif 0
│  ├─ @if(node.kind === 'include')ip4:188.172.128.0/20@elseif(node.kind === 'all')ip4:188.172.128.0/20@elseif(node.kind === 'root')ip4:188.172.128.0/20@elseip4:188.172.128.0/20@endif 0
│  ├─ @if(node.kind === 'include')ip4:192.161.144.0/20@elseif(node.kind === 'all')ip4:192.161.144.0/20@elseif(node.kind === 'root')ip4:192.161.144.0/20@elseip4:192.161.144.0/20@endif 0
│  ├─ @if(node.kind === 'include')ip4:216.198.0.0/18@elseif(node.kind === 'all')ip4:216.198.0.0/18@elseif(node.kind === 'root')ip4:216.198.0.0/18@elseip4:216.198.0.0/18@endif 0
│  └─ @if(node.kind === 'include')~all@elseif(node.kind === 'all')~all@elseif(node.kind === 'root')~all@else~all@endif 0
├─ @if(node.kind === 'include')include:_spf.salesforce.com@elseif(node.kind === 'all')include:_spf.salesforce.com@elseif(node.kind === 'root')include:_spf.salesforce.com@elseinclude:_spf.salesforce.com@endif +1
│  ├─ @if(node.kind === 'include')exists:%{i}._spf.mta.salesforce.com@elseif(node.kind === 'all')exists:%{i}._spf.mta.salesforce.com@elseif(node.kind === 'root')exists:%{i}._spf.mta.salesforce.com@elseexists:%{i}._spf.mta.salesforce.com@endif +1
│  └─ @if(node.kind === 'include')-all@elseif(node.kind === 'all')-all@elseif(node.kind === 'root')-all@else-all@endif 0
├─ @if(node.kind === 'include')include:servers.mcsv.net@elseif(node.kind === 'all')include:servers.mcsv.net@elseif(node.kind === 'root')include:servers.mcsv.net@elseinclude:servers.mcsv.net@endif +1
│  ├─ @if(node.kind === 'include')ip4:205.201.128.0/20@elseif(node.kind === 'all')ip4:205.201.128.0/20@elseif(node.kind === 'root')ip4:205.201.128.0/20@elseip4:205.201.128.0/20@endif 0
│  ├─ @if(node.kind === 'include')ip4:198.2.128.0/18@elseif(node.kind === 'all')ip4:198.2.128.0/18@elseif(node.kind === 'root')ip4:198.2.128.0/18@elseip4:198.2.128.0/18@endif 0
│  ├─ @if(node.kind === 'include')ip4:148.105.0.0/16@elseif(node.kind === 'all')ip4:148.105.0.0/16@elseif(node.kind === 'root')ip4:148.105.0.0/16@elseip4:148.105.0.0/16@endif 0
│  └─ @if(node.kind === 'include')-all@elseif(node.kind === 'all')-all@elseif(node.kind === 'root')-all@else-all@endif 0
├─ @if(node.kind === 'include')include:mktomail.com@elseif(node.kind === 'all')include:mktomail.com@elseif(node.kind === 'root')include:mktomail.com@elseinclude:mktomail.com@endif +1
│  ├─ @if(node.kind === 'include')ip4:199.15.212.0/22@elseif(node.kind === 'all')ip4:199.15.212.0/22@elseif(node.kind === 'root')ip4:199.15.212.0/22@elseip4:199.15.212.0/22@endif 0
│  ├─ @if(node.kind === 'include')ip4:72.3.185.0/24@elseif(node.kind === 'all')ip4:72.3.185.0/24@elseif(node.kind === 'root')ip4:72.3.185.0/24@elseip4:72.3.185.0/24@endif 0
│  ├─ @if(node.kind === 'include')ip4:72.32.154.0/24@elseif(node.kind === 'all')ip4:72.32.154.0/24@elseif(node.kind === 'root')ip4:72.32.154.0/24@elseip4:72.32.154.0/24@endif 0
│  ├─ @if(node.kind === 'include')ip4:72.32.217.0/24@elseif(node.kind === 'all')ip4:72.32.217.0/24@elseif(node.kind === 'root')ip4:72.32.217.0/24@elseip4:72.32.217.0/24@endif 0
│  ├─ @if(node.kind === 'include')ip4:72.32.243.0/24@elseif(node.kind === 'all')ip4:72.32.243.0/24@elseif(node.kind === 'root')ip4:72.32.243.0/24@elseip4:72.32.243.0/24@endif 0
│  ├─ @if(node.kind === 'include')ip4:94.236.119.0/26@elseif(node.kind === 'all')ip4:94.236.119.0/26@elseif(node.kind === 'root')ip4:94.236.119.0/26@elseip4:94.236.119.0/26@endif 0
│  ├─ @if(node.kind === 'include')ip4:37.188.97.188/32@elseif(node.kind === 'all')ip4:37.188.97.188/32@elseif(node.kind === 'root')ip4:37.188.97.188/32@elseip4:37.188.97.188/32@endif 0
│  ├─ @if(node.kind === 'include')ip4:185.28.196.0/22@elseif(node.kind === 'all')ip4:185.28.196.0/22@elseif(node.kind === 'root')ip4:185.28.196.0/22@elseip4:185.28.196.0/22@endif 0
│  ├─ @if(node.kind === 'include')ip4:192.28.128.0/18@elseif(node.kind === 'all')ip4:192.28.128.0/18@elseif(node.kind === 'root')ip4:192.28.128.0/18@elseip4:192.28.128.0/18@endif 0
│  ├─ @if(node.kind === 'include')ip4:103.237.104.0/22@elseif(node.kind === 'all')ip4:103.237.104.0/22@elseif(node.kind === 'root')ip4:103.237.104.0/22@elseip4:103.237.104.0/22@endif 0
│  ├─ @if(node.kind === 'include')ip4:130.248.172.0/24@elseif(node.kind === 'all')ip4:130.248.172.0/24@elseif(node.kind === 'root')ip4:130.248.172.0/24@elseip4:130.248.172.0/24@endif 0
│  ├─ @if(node.kind === 'include')ip4:130.248.173.0/24@elseif(node.kind === 'all')ip4:130.248.173.0/24@elseif(node.kind === 'root')ip4:130.248.173.0/24@elseip4:130.248.173.0/24@endif 0
│  └─ @if(node.kind === 'include')~all@elseif(node.kind === 'all')~all@elseif(node.kind === 'root')~all@else~all@endif 0
├─ @if(node.kind === 'include')include:sendgrid.net@elseif(node.kind === 'all')include:sendgrid.net@elseif(node.kind === 'root')include:sendgrid.net@elseinclude:sendgrid.net@endif +1
│  ├─ @if(node.kind === 'include')ip4:167.89.0.0/17@elseif(node.kind === 'all')ip4:167.89.0.0/17@elseif(node.kind === 'root')ip4:167.89.0.0/17@elseip4:167.89.0.0/17@endif 0
│  ├─ @if(node.kind === 'include')ip4:208.117.48.0/20@elseif(node.kind === 'all')ip4:208.117.48.0/20@elseif(node.kind === 'root')ip4:208.117.48.0/20@elseip4:208.117.48.0/20@endif 0
│  ├─ @if(node.kind === 'include')ip4:50.31.32.0/19@elseif(node.kind === 'all')ip4:50.31.32.0/19@elseif(node.kind === 'root')ip4:50.31.32.0/19@elseip4:50.31.32.0/19@endif 0
│  ├─ @if(node.kind === 'include')ip4:198.37.144.0/20@elseif(node.kind === 'all')ip4:198.37.144.0/20@elseif(node.kind === 'root')ip4:198.37.144.0/20@elseip4:198.37.144.0/20@endif 0
│  ├─ @if(node.kind === 'include')ip4:198.21.0.0/21@elseif(node.kind === 'all')ip4:198.21.0.0/21@elseif(node.kind === 'root')ip4:198.21.0.0/21@elseip4:198.21.0.0/21@endif 0
│  ├─ @if(node.kind === 'include')ip4:192.254.112.0/20@elseif(node.kind === 'all')ip4:192.254.112.0/20@elseif(node.kind === 'root')ip4:192.254.112.0/20@elseip4:192.254.112.0/20@endif 0
│  ├─ @if(node.kind === 'include')ip4:168.245.0.0/17@elseif(node.kind === 'all')ip4:168.245.0.0/17@elseif(node.kind === 'root')ip4:168.245.0.0/17@elseip4:168.245.0.0/17@endif 0
│  ├─ @if(node.kind === 'include')ip4:149.72.0.0/16@elseif(node.kind === 'all')ip4:149.72.0.0/16@elseif(node.kind === 'root')ip4:149.72.0.0/16@elseip4:149.72.0.0/16@endif 0
│  ├─ @if(node.kind === 'include')ip4:159.183.0.0/16@elseif(node.kind === 'all')ip4:159.183.0.0/16@elseif(node.kind === 'root')ip4:159.183.0.0/16@elseip4:159.183.0.0/16@endif 0
│  ├─ @if(node.kind === 'include')ip4:134.128.64.0/19@elseif(node.kind === 'all')ip4:134.128.64.0/19@elseif(node.kind === 'root')ip4:134.128.64.0/19@elseip4:134.128.64.0/19@endif 0
│  ├─ @if(node.kind === 'include')ip4:134.128.96.0/19@elseif(node.kind === 'all')ip4:134.128.96.0/19@elseif(node.kind === 'root')ip4:134.128.96.0/19@elseip4:134.128.96.0/19@endif 0
│  ├─ @if(node.kind === 'include')include:ab.sendgrid.net@elseif(node.kind === 'all')include:ab.sendgrid.net@elseif(node.kind === 'root')include:ab.sendgrid.net@elseinclude:ab.sendgrid.net@endif +1
│  │  ├─ @if(node.kind === 'include')ip4:223.165.113.0/24@elseif(node.kind === 'all')ip4:223.165.113.0/24@elseif(node.kind === 'root')ip4:223.165.113.0/24@elseip4:223.165.113.0/24@endif 0
│  │  ├─ @if(node.kind === 'include')ip4:223.165.115.0/24@elseif(node.kind === 'all')ip4:223.165.115.0/24@elseif(node.kind === 'root')ip4:223.165.115.0/24@elseip4:223.165.115.0/24@endif 0
│  │  ├─ @if(node.kind === 'include')ip4:223.165.118.0/23@elseif(node.kind === 'all')ip4:223.165.118.0/23@elseif(node.kind === 'root')ip4:223.165.118.0/23@elseip4:223.165.118.0/23@endif 0
│  │  ├─ @if(node.kind === 'include')ip4:223.165.120.0/23@elseif(node.kind === 'all')ip4:223.165.120.0/23@elseif(node.kind === 'root')ip4:223.165.120.0/23@elseip4:223.165.120.0/23@endif 0
│  │  └─ @if(node.kind === 'include')~all@elseif(node.kind === 'all')~all@elseif(node.kind === 'root')~all@else~all@endif 0
│  └─ @if(node.kind === 'include')~all@elseif(node.kind === 'all')~all@elseif(node.kind === 'root')~all@else~all@endif 0
├─ @if(node.kind === 'include')ip4:62.253.227.114@elseif(node.kind === 'all')ip4:62.253.227.114@elseif(node.kind === 'root')ip4:62.253.227.114@elseip4:62.253.227.114@endif 0
├─ @if(node.kind === 'include')ip4:166.78.69.169@elseif(node.kind === 'all')ip4:166.78.69.169@elseif(node.kind === 'root')ip4:166.78.69.169@elseip4:166.78.69.169@endif 0
├─ @if(node.kind === 'include')ip4:166.78.69.170@elseif(node.kind === 'all')ip4:166.78.69.170@elseif(node.kind === 'root')ip4:166.78.69.170@elseip4:166.78.69.170@endif 0
├─ @if(node.kind === 'include')ip4:166.78.71.131@elseif(node.kind === 'all')ip4:166.78.71.131@elseif(node.kind === 'root')ip4:166.78.71.131@elseip4:166.78.71.131@endif 0
└─ @if(node.kind === 'include')~all@elseif(node.kind === 'all')~all@elseif(node.kind === 'root')~all@else~all@endif 0
Total DNS lookups10 / 10
Raw TXT record
github.com.        3600    IN    TXT    "v=spf1 ip4:192.30.252.0/22 include:spf.protection.outlook.com include:_netblocks.google.com include:_netblocks2.google.com include:mail.zendesk.com include:_spf.salesforce.com include:servers.mcsv.net include:mktomail.com include:sendgrid.net ip4:62.253.227.114 ip4:166.78.69.169 ip4:166.78.69.170 ip4:166.78.71.131 ~all"
Guide

Reading an SPF record

SPF (Sender Policy Framework) is a single DNS TXT record that lists which servers are allowed to send mail for your domain. This SPF record checker reads the published v=spf1 value, validates SPF DNS syntax, and explains every mechanism in the sender policy.

The most common failure is the 10-lookup limit: every include, a, mx, ptr, exists and redirect term costs a DNS query, and nested includes count too. Cross 10 and the whole record returns a PermError. The ip4 and ip6 terms are free, so flatten stable includes into ranges where you can.

SPF helps receivers evaluate whether the connecting server is authorized, but it is not a complete anti-spoofing system by itself. Pair SPF with DKIM and a DMARC policy so receivers can also evaluate domain alignment and reporting.

FAQ

Frequently asked questions

What is an SPF record checker?

An SPF record checker validates a domain TXT record that starts with v=spf1. It parses mechanisms such as include, ip4, ip6, a, mx, redirect, and all so you can understand the authorized mail sender policy.

What is the SPF 10 DNS lookup limit?

RFC 7208 caps SPF evaluation at 10 DNS-querying mechanisms, including include, a, mx, ptr, exists, and redirect. Nested includes count toward the same budget; exceeding it causes a PermError.

Should I use ~all or -all?

Start with ~all while confirming every legitimate sender is listed, then move to -all when ready. SPF alone does not guarantee inbox placement, so pair it with DKIM and DMARC alignment.

Why can I only have one SPF record?

Publishing more than one v=spf1 TXT record creates a PermError. Merge all authorized senders into a single SPF record using mechanisms such as include, ip4, ip6, a, and mx.