Sender Policy Framework (SPF) is a DNS-based email authentication protocol that specifies which mail servers are authorized to send email on behalf of your domain. Despite being one of the oldest email authentication standards, SPF remains a critical component of the email security triad — alongside DKIM and DMARC — that determines whether your messages reach the inbox or get flagged as spam.
In 2026, SPF record setup is more important than ever. With Google and Yahoo’s bulk sender requirements now fully enforced, Microsoft’s expanded authentication checks, and the ongoing rise in domain spoofing attacks, a properly configured SPF record is non-negotiable for any organization sending email at scale.
This guide walks you through complete SPF configuration — from understanding the syntax to deploying records for major email providers — with practical examples you can implement today.
An SPF record is published as a DNS TXT record on your domain. Every SPF record follows a specific structure:
v=spf1 [mechanisms] [qualifier]all
Let’s break down each component:
Every SPF record must begin with v=spf1. This identifies the TXT record as an SPF record. There is no “v=spf2” — the version has remained at 1 since the protocol’s inception in RFC 7208.
v=spf1 ip4:192.168.1.0/24 include:_spf.google.com -all
This record authorizes:
-all)Mechanisms are the core directives that define which servers are permitted to send mail. Here’s every mechanism you need to know:
ip4 — IPv4 Address or RangeAuthorizes a specific IPv4 address or CIDR range.
v=spf1 ip4:203.0.113.50 ip4:198.51.100.0/24 -all
Use this when you know the exact IP addresses of your mail servers. This is the most precise mechanism and doesn’t consume a DNS lookup.
ip6 — IPv6 Address or RangeAuthorizes a specific IPv6 address or range.
v=spf1 ip6:2001:db8::1 ip6:2001:db8::/32 -all
With IPv6 adoption continuing to grow in 2026, always include ip6 mechanisms if your infrastructure supports dual-stack mail delivery.
include — Reference Another Domain’s SPFDelegates authorization to another domain’s SPF record. This is the mechanism you’ll use most frequently when authorizing third-party email services.
v=spf1 include:_spf.google.com include:spf.protection.outlook.com -all
Important: Each include consumes at least one DNS lookup, and the included domain’s own lookups count against your 10-lookup limit.
a — Domain’s A RecordAuthorizes the IP address(es) in the domain’s A record to send mail.
v=spf1 a -all
This means “the same server that hosts my website is allowed to send email.” You can also reference another domain: a:mail.example.com.
mx — Domain’s MX RecordsAuthorizes the IP addresses of all servers listed in the domain’s MX records.
v=spf1 mx -all
This says “any server that receives mail for my domain is also allowed to send mail.” Each unique MX hostname consumes a DNS lookup.
exists — Macro-Based Existence CheckAn advanced mechanism that checks whether a specific DNS A record exists. Used primarily for per-user SPF policies and advanced configurations.
v=spf1 exists:%{i}._spf.example.com -all
redirect — Replace With Another RecordNot technically a mechanism but a modifier — redirect points the entire SPF evaluation to another domain’s record. Unlike include, it completely replaces evaluation rather than adding to it.
v=spf1 redirect=_spf.example.com
Qualifiers prefix mechanisms and define what happens when a mechanism matches. There are four qualifiers:
| Qualifier | Symbol | Meaning | Recommendation |
|---|---|---|---|
| Pass | + |
Authorized (default if omitted) | Implicit — rarely written explicitly |
| Hard Fail | - |
Not authorized, reject the message | Use for production domains with full confidence |
| Soft Fail | ~ |
Not authorized, but accept with suspicion | Use during migration or testing phases |
| Neutral | ? |
No assertion made | Rarely useful — avoid in production |
-all and ~allIn 2026, the practical difference between -all (hard fail) and ~all (soft fail) has narrowed significantly. Most receiving servers treat both similarly when combined with a DMARC policy of p=reject or p=quarantine. However, best practice is:
-all when you’re confident you’ve identified all legitimate sending sources~all during initial deployment or when you’re still auditing sending sources+all — this authorizes the entire internet to send as your domainHere are ready-to-use SPF configurations for the most common email platforms in 2026:
v=spf1 include:_spf.google.com -all
v=spf1 include:spf.protection.outlook.com -all
v=spf1 include:amazonses.com -all
For region-specific SES endpoints:
v=spf1 include:amazonses.com include:ses.us-east-1.amazonaws.com -all
v=spf1 include:_spf.google.com include:amazonses.com -all
v=spf1 include:spf.protection.outlook.com include:sendgrid.net ip4:203.0.113.50 -all
v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:amazonses.com include:sendgrid.net -all
Warning: This four-include record is already consuming a significant number of DNS lookups. Always verify your total lookup count after adding providers.
This is where most SPF configurations break. RFC 7208 imposes a strict limit: SPF evaluation must not require more than 10 DNS lookups. Exceeding this limit results in a permerror, and many receivers treat this the same as having no SPF record at all.
include: — 1 lookup (plus the included domain’s own lookups)a — 1 lookupmx — 1 lookup per MX record resolvedredirect= — 1 lookupexists: — 1 lookupip4: — no lookup requiredip6: — no lookup requiredall — no lookup requiredUse command-line tools to recursively resolve your SPF record:
dig TXT example.com +short
dig TXT _spf.google.com +short
Or use online SPF validation tools that visualize the full lookup tree. Count every include, a, mx, redirect, and exists mechanism across all nested records.
include with ip4/ip6 — If a provider’s IPs are stable, hardcode them (but monitor for changes)mail.example.com with its own SPF record separate from your root domainFollow these steps to deploy a proper SPF record for your domain:
Before writing any DNS record, identify every system that sends email using your domain:
Check each provider’s documentation for their required SPF include. Common values:
include:_spf.google.cominclude:spf.protection.outlook.cominclude:amazonses.cominclude:sendgrid.netinclude:servers.mcsv.netinclude:spf.mtasv.netBuild the record with all authorized sources. Start with ~all during testing:
v=spf1 include:_spf.google.com include:amazonses.com ip4:203.0.113.50 ~all
Log into your DNS provider and create (or update) the TXT record:
@ (root domain) or subdomainAfter publishing, verify with a DNS query:
dig TXT example.com +short
Confirm only one SPF TXT record exists (multiple SPF records cause failures).
Send test emails to Gmail, Outlook, and Yahoo accounts. Check headers for spf=pass in the Authentication-Results header.
After 2–4 weeks of successful delivery with no SPF failures in your DMARC reports, switch from ~all to -all:
v=spf1 include:_spf.google.com include:amazonses.com ip4:203.0.113.50 -all
A domain must have exactly one SPF TXT record. Publishing two causes permerror on all emails.
Wrong:
v=spf1 include:_spf.google.com -all
v=spf1 include:amazonses.com -all
Correct:
v=spf1 include:_spf.google.com include:amazonses.com -all
Adding every service’s include without counting lookups. Always check the recursive lookup tree before publishing.
+allThis authorizes everyone on the internet to send as your domain. Never use it — not even in testing.
SPF records do not inherit from parent domains. If you send email from notifications.example.com, it needs its own SPF record.
If you migrated from one provider to another but left the old include, you’re authorizing servers you no longer control. Audit quarterly.
ptr MechanismThe ptr mechanism is deprecated in RFC 7208 and should not be used. It’s slow, unreliable, and many receivers ignore it entirely.
When SPF checks fail, here’s how to diagnose the issue:
In any received email, look for the Authentication-Results header:
Authentication-Results: mx.google.com;
spf=fail (google.com: domain of [email protected] does not
designate 198.51.100.22 as permitted sender)
[email protected]
This tells you the exact IP that was checked and why it failed.
| Symptom | Likely Cause | Fix |
|---|---|---|
spf=fail |
Sending IP not in SPF record | Add the IP or provider’s include |
spf=permerror |
Too many lookups or syntax error | Flatten record or fix syntax |
spf=temperror |
DNS timeout during lookup | Check DNS server reliability |
spf=none |
No SPF record found | Publish an SPF record |
spf=softfail |
IP not authorized, but using ~all |
Add the source or switch to -all when ready |
DMARC aggregate reports (RUA) reveal every IP that sends email using your domain, along with SPF and DKIM pass/fail results. Review these weekly to catch unauthorized senders and misconfigured services early.
v=spf1 -all to prevent spoofingDNS propagation typically takes 15 minutes to 48 hours, depending on TTL settings and caching. With a TTL of 3600, most resolvers will pick up your new record within 1–2 hours.
No. RFC 7208 requires exactly one SPF TXT record per domain. Multiple records cause a permerror result, effectively breaking SPF authentication for all your email.
The receiving server returns a permerror, meaning SPF evaluation cannot complete. Most receivers treat this as an SPF failure, which can impact delivery — especially if your DMARC policy relies on SPF alignment.
SPF often breaks with traditional email forwarding because the forwarding server’s IP isn’t in the original sender’s SPF record. This is one reason DKIM is essential — it survives forwarding intact. ARC (Authenticated Received Chain) also helps preserve authentication through forwarding hops.
SPF flattening resolves all includes into IP addresses, reducing lookup count. It’s effective but requires automated updates since provider IPs can change. Use a managed flattening service rather than manually maintaining flattened records.
A single DNS TXT string is limited to 255 characters, but DNS allows multiple strings to be concatenated in one TXT record (up to the overall UDP response limit of 512 bytes without EDNS, or ~4096 bytes with EDNS). Keep your record under 450 characters to ensure reliable resolution across all DNS infrastructure.