Complete SPF Record Guide
Sender Policy Framework (SPF) is a DNS-based record that tells receiving mail servers which hosts are allowed to send email for your domain. When a message arrives, the receiver looks up your SPF record, checks the connecting IP against the mechanisms you defined, and decides whether SPF passes or fails. SPF does not sign message content—that's DKIM—and it does not tell receivers what to do when auth fails—that's DMARC. All three work together: SPF authorizes infrastructure, DKIM authenticates the message, and DMARC applies policy.
This guide covers syntax, mechanisms, qualifiers, the DNS lookup limit that causes permerrors, and how to avoid common mistakes. Use it as a reference when building or troubleshooting SPF records.
What SPF is and how SPF works
When a receiving server gets an email, it checks the Return-Path (or MAIL FROM) domain, does a DNS TXT lookup for that domain, and looks for a record starting with v=spf1. If it finds one, it evaluates the mechanisms in order. The first mechanism that matches determines the result: pass, fail, softfail, or neutral. If no mechanism matches, the default is neutral unless the final mechanism is -all, in which case a non-match means fail.
SPF checks happen at the edge. The receiver does not inspect the body or headers beyond what it needs to perform the lookup and compare IPs. That simplicity is both a strength—it's fast and predictable—and a limitation, since SPF says nothing about whether the visible From domain aligns with the authenticated domain. That's why DMARC matters.
The authenticated domain for SPF is the domain in the envelope (Return-Path), not the From header. A message can "pass" SPF for a subdomain used in Return-Path while the visible From shows your main domain. DMARC checks that alignment and decides whether to accept, quarantine, or reject based on your policy. Getting SPF right is the foundation; DMARC layers policy on top.
SPF record syntax explained
Every valid SPF record starts with v=spf1. The rest is a sequence of mechanisms, each optionally prefixed by a qualifier (+, -, ~, or ?). Mechanisms are separated by whitespace. Order matters: evaluation stops at the first match.
A minimal record is v=spf1 -all: it fails everyone except explicitly matched IPs. A typical record adds mechanisms before the final all to authorize your providers. Mechanisms are evaluated left to right; the first match wins. That means order can matter: put the most specific or common cases first if you want to optimize for clarity. For detailed syntax rules and edge cases, see the SPF record syntax explained page.
SPF mechanisms explained
include
include:domain pulls in the SPF policy of another domain. The receiver performs a separate DNS lookup and evaluates that domain's record as if it were your own. Include is how you authorize providers like Google, Microsoft, or SendGrid without hardcoding their IP ranges. Each include counts toward the 10-lookup limit.
ip4 and ip6
ip4:1.2.3.4 or ip4:1.2.3.0/24 matches the connecting IPv4 address. ip6 does the same for IPv6. These do not trigger extra DNS lookups, so they're efficient for static IPs you control. When you add a new outbound server, you must update the record; include mechanisms avoid that by delegating to the provider's maintained list.
a and mx
a uses the A records of the current domain (or a specified domain) to authorize IPs. mx uses the MX hosts. Both cause additional lookups. Many deployments avoid them in favor of explicit ip4 or include to stay under the lookup limit.
redirect
redirect=example.com delegates the entire policy to another domain. The receiver fetches that domain's SPF record and uses it. Useful when you want a single source of truth. See SPF redirect explained for when and how to use it.
all
all matches any IP. It must appear last and is always prefixed by a qualifier. -all means "fail everyone else"; ~all means "softfail everyone else." You should have exactly one all mechanism. If it's missing, your policy is incomplete—see SPF missing all mechanism for why.
SPF qualifiers explained
Each mechanism can be preceded by a qualifier that defines the result when that mechanism matches:
+(pass) — default if omitted; the message passes SPF.-(fail) — hard fail; the receiver should reject.~(softfail) — treat as suspicious but don't hard fail. Often used during rollout.?(neutral) — no strong signal either way.
Most records end with ~all during testing and -all once enforcement is stable. For the tradeoffs, see SPF softfail vs fail.
DNS lookup limit and SPF permerror
SPF allows at most 10 DNS lookups during evaluation. Each include, redirect, a, and mx (and nested includes) counts. If the limit is exceeded, SPF returns a permanent error (permerror), and receivers treat your policy as invalid. Legitimate mail can fail SPF even when it should pass.
To fix this, reduce includes, use SPF include flattening where appropriate, and avoid chaining too many providers. The SPF permerror: too many DNS lookups guide walks through how to identify and fix lookup bloat.
Common SPF mistakes
- Multiple SPF records. A domain may publish only one SPF record. Two or more cause permerror. Merge them into a single policy—see multiple SPF records found.
- Syntax errors. Typos, missing colons, or malformed mechanisms break evaluation. Use SPF record syntax error for common fixes.
- Exceeding the 10-lookup limit. Too many includes or chained policies trigger permerror.
- Missing
all. Without a final~allor-all, your policy is incomplete and may default to neutral in unclear ways. - Wrong qualifier at the end. Using
?allor omittingallweakens the fail signal for unauthorized senders.
SPF record examples
Google Workspace
v=spf1 include:_spf.google.com ~allThis authorizes Google's sending infrastructure. Use -all if you want hard fail for non-Google senders.
Microsoft 365
v=spf1 include:spf.protection.outlook.com -allIf you use Exchange Online Protection or Microsoft 365, this include covers their outbound IPs.
SendGrid
v=spf1 include:sendgrid.net ~allHybrid setup (Google + SendGrid)
v=spf1 include:_spf.google.com include:sendgrid.net ~allAdd one include per provider. Keep the list minimal to stay under the lookup limit. For more examples and copy-paste templates, see SPF record examples and the SPF record generator.
How to troubleshoot SPF step by step
- Run a live check. Use our domain checker or another SPF validator to see what receivers see.
- Confirm you have exactly one SPF record. Multiple records invalidate the policy.
- Verify syntax. Look for typos, missing colons, and malformed mechanisms.
- Count lookups. If you use many includes, trace each one and ensure the total stays under 10.
- Confirm the sending IP is authorized. Add the correct include or ip4 mechanism for the service that actually sends your mail.
- Allow time for DNS propagation, then re-check. Changes can take up to 48 hours in rare cases.
SPF best practices for stable email delivery
- Publish one SPF record per domain. Never split policy across multiple TXT records.
- List only providers that actually send mail for your domain. Extra includes add lookups and complexity.
- Prefer
includeover hardcoded IP ranges when the provider supports it. They maintain their own IPs; you stay current. - End with
~allduring rollout, then move to-allonce you're confident no legitimate senders are excluded. - Monitor DMARC reports. They reveal SPF failures and alignment issues you might miss from a single check.
- Stabilize SPF before tightening DMARC. Fix authorization first; then enforce policy.
- Use a single TXT record. DNS allows multiple TXT records for the same name, but SPF permits only one that starts with
v=spf1. Splitting across records causes permerror.
Check your domain
Run a live SPF, DKIM, and DMARC check. No login, no saved data.
Run email authentication check