Why validate SPF syntax before publishing?
A malformed SPF (Sender Policy Framework) record can have immediate consequences: rejected emails, disabled authentication, or worse, a false sense of security. Syntax validation catches these problems before they impact your deliverability.
Three main use cases:
- New SPF -> Validate structure before first publication
- SPF modification -> Verify that changes don't introduce errors
- Deliverability diagnosis -> Confirm that syntax isn't causing rejections
How to use the validator in 3 steps
Step 1: Copy the SPF record
Retrieve your record from:
- Your DNS interface (GoDaddy, Cloudflare, Route 53, etc.)
- A DNS lookup tool
- Directly from your text editor if you're writing it
Expected format:
v=spf1 ip4:203.0.113.0/24 include:_spf.google.com -all
Step 2: Paste into the validator
Paste the complete record into the form above. The tool automatically analyzes:
- ✅ Base structure (v=spf1)
- ✅ Mechanisms (ip4, ip6, mx, a, include, exists, ptr)
- ✅ Modifiers (redirect, exp)
- ✅ Qualifiers (+, -, ~, ?)
- ✅ Final directive (all)
Step 2b: Test an IP (optional)
Enter an IP address in the dedicated field to check if it's authorized by the SPF policy:
- Pass (green): The IP is explicitly authorized
- Fail (red): The IP is explicitly rejected
- Softfail (amber): The IP is not authorized but not strictly rejected
- Neutral (gray): No match or no opinion
The tool evaluates mechanisms in order (ip4, ip6, a, mx, include) per RFC 7208 §4.6.2.
Step 3: Fix and publish
The report displays:
- Errors (red): Blocking issues to fix
- Warnings (orange): Security risks or best practices
- Information (blue): Details about the analyzed structure
Fix the errors, then publish to your DNS.
What is SPF syntax?
An SPF record is a character string published in a DNS TXT record. Its syntax follows a precise structure defined by RFC 7208:
v=spf1 [qualifier]mechanism [modifier] ... final_directive
Components:
| Element | Examples | Role |
|---|---|---|
| Version | v=spf1 | Required, always first |
| Qualifier | +, -, ~, ? | Determines action (pass, fail, softfail, neutral) |
| Mechanism | ip4:, mx, include:, a: | Defines authorized senders |
| Modifier | redirect=, exp= | Additional options |
| Final directive | -all, ~all, ?all | Default action for non-matches |
What exactly does the validator analyze?
Syntax errors
| Error code | Description | Impact |
|---|---|---|
missing_version | Missing v=spf1 | SPF ignored (permerror) |
unknown_mechanism | Unrecognized mechanism | Invalid SPF |
mechanism_missing_value | include: without domain | Invalid SPF |
mechanism_invalid_value | Malformed IP or CIDR | Invalid SPF |
duplicate_modifier | Two redirect= | Invalid SPF |
multiple_all | Multiple all directives | Invalid SPF |
Security warnings
| Code | Description | Risk |
|---|---|---|
weak_qualifier | ?all (neutral) | No protection |
permissive_all | +all | Authorizes everyone |
softfail_all | ~all without transition to -all | Partial protection |
DNS limits
| Code | Description | RFC limit |
|---|---|---|
lookup_limit_exceeded | More than 10 DNS lookups | 10 max |
void_lookup_limit_exceeded | Too many void responses | 2 max |
lookup_cycle | Reference loop | Forbidden |
Concrete use cases
Case 1: New domain, first SPF
Situation: You're setting up email for captaindns.com with Google Workspace.
Action: Validate before publishing:
v=spf1 include:_spf.google.com -all
Expected result:
- ✅ Valid syntax
- ✅ 1 DNS lookup (under the 10 limit)
- ✅ Strict final directive (-all)
Case 2: Adding a new marketing service
Situation: You're adding Mailchimp to your existing SPF.
Current SPF:
v=spf1 include:_spf.google.com -all
Modified SPF:
v=spf1 include:_spf.google.com include:servers.mcsv.net -all
Validation: Confirm that the addition doesn't exceed 10 lookups and that the syntax remains valid.
Case 3: "permerror" in production
Symptom: Your emails fail with SPF permerror.
Diagnosis: Paste the record into the validator.
Detected error:
v=spf1 ip4:192.168.1.1 include: -all
Error: mechanism_missing_value - include: without domain.
Fix:
v=spf1 ip4:192.168.1.1 include:_spf.captaindns.com -all
Case 4: Too many DNS lookups
Symptom: The validator shows lookup_limit_exceeded.
Diagnosis: Your SPF has too many includes:
v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:amazonses.com include:_spf.salesforce.com include:sendgrid.net include:mailchimp.com -all
Solutions:
- Replace some includes with direct ip4/ip6
- Use a dedicated subdomain (e.g.,
marketing.captaindns.com) - Remove unused services
- Use our SPF Flattener to automatically resolve includes into IPs
Test an IP against the SPF policy
Why test an IP against an SPF record?
When an email is received, the recipient server checks if the sender's IP is authorized by the domain's SPF record. If the IP isn't covered, the email may be rejected or flagged as suspicious.
Common use cases:
- New mail server -> Verify its IP is covered before the first send
- Third-party service (Mailchimp, SendGrid, SES) -> Confirm the include covers the provider's IPs
- "SPF fail" diagnosis -> Identify exactly which mechanism rejects the IP
- Server migration -> Test new IPs before decommissioning old ones
How does the IP test work?
The tool evaluates the SPF record mechanism by mechanism, in order:
- ip4/ip6: Direct IP or CIDR match
- a: DNS resolution of the domain, comparison with the IP
- mx: MX server resolution, then their IP resolution
- include: Recursive evaluation of the included domain's SPF
- all: Universal match (result depends on qualifier)
The first matching mechanism determines the result. If none match and there's no all directive, the result is "neutral".
FAQ - Frequently asked questions
Q: What is an SPF record?
A: SPF (Sender Policy Framework) is a DNS TXT record that lists servers authorized to send emails for your domain. Format: v=spf1 followed by mechanisms (ip4, mx, include) and a final directive (-all, ~all).
Q: Why validate SPF syntax before publishing?
A: A malformed SPF record generates a permanent error (permerror) that can reject all your emails or completely disable SPF verification. Validating before publishing prevents service interruptions.
Q: What is the DNS lookup limit for SPF?
A: RFC 7208 limits SPF evaluation to 10 DNS lookups. Each include, a, mx, ptr and exists counts. Exceeding this limit generates a permerror and may fail authentication.
Q: What does the qualifier -all vs ~all mean?
A:
-all(hard fail): Rejects unauthorized emails~all(soft fail): Marks as suspicious but accepts
Start with ~all for testing, then switch to -all in production for maximum protection.
Q: How do I fix the "too many DNS lookups" error?
A:
- Replace includes with direct
ip4/ip6 - Remove unused mechanisms
- Use subdomains with their own SPF
- Avoid
ptr(deprecated and costly in lookups)
Q: Can I have multiple SPF records?
A: No. The RFC requires a single SPF record per domain. Multiple records generate a permerror. Merge your policies into one TXT starting with v=spf1.
Q: Does the tool validate included domains?
A: The validator checks the syntax of domains referenced by include and redirect. For complete analysis with DNS resolution and recursive lookup counting, use the SPF Inspector.
Complementary tools
| Tool | Purpose |
|---|---|
| SPF Inspector | Analyze a published SPF with complete DNS resolution |
| SPF Flattener | Flatten your SPF to stay under the 10 DNS lookup limit |
| DKIM Inspector | Validate your DKIM signature |
| DMARC Inspector | Configure and test your DMARC policy |
| Email Header Analyzer | Diagnose SPF/DKIM/DMARC on a received email |
Useful resources
- RFC 7208 - Sender Policy Framework (official SPF specification)
- Google - Set up SPF (Google Workspace guide)
- Microsoft - SPF for Microsoft 365 (Outlook/M365 guide)