SPF Record Syntax: Complete Reference
Every SPF mechanism, qualifier, and lookup limit explained with copy-paste examples for M365, Google Workspace, and ESP mail.

You copy an SPF record from a vendor doc. Paste it into DNS. Mail breaks the next morning. A 33-person fintech in Dublin added include:sendgrid.net to an already crowded TXT record in November 2025. The record looked valid in a basic TXT lookup. SPF evaluation returned permerror. DMARC failed on the SPF leg. Onboarding emails bounced at two banks' gateways. The include was syntactically fine. The total DNS lookup count was twelve. SPF (Sender Policy Framework) answers one question: is this IP address allowed to send mail claiming to be from this domain? The spf record syntax looks simple. One TXT string starting with v=spf1. Under the hood, receivers walk mechanisms left to right, chase DNS lookups, and stop hard at ten evaluations per RFC 7208. This guide is the complete reference we use before touching production DNS: every common mechanism, qualifier, modifier, failure mode, and the M365/Google/ESP patterns that actually work in 2026.
SPF Basics: What Gets Published Where
Record location
Publish SPF as a single TXT record on the domain that appears in the SMTP envelope-from (Return-Path), usually the root domain or a dedicated bounce subdomain.
Version token
Every record must start with v=spf1 followed by a space and one or more mechanisms. Only one SPF TXT per domain. Two records = permerror.
How receivers evaluate
Receiving MTAs fetch the TXT record, parse mechanisms in order, and match the connecting IP against each mechanism until one matches or the record ends with the default result from all.
SPF is not inbox placement
SPF pass authorizes an IP for the envelope domain. DMARC still requires alignment with the visible From: header. SPF pass alone does not guarantee inbox placement.
Mechanisms and Qualifiers (The Building Blocks)
Each mechanism can be prefixed with a qualifier. Default qualifier is + (pass), usually omitted.
| Qualifier | Meaning | Example |
|---|---|---|
| + pass | Match = authorized | ip4:203.0.113.10 |
| - fail | Match = not authorized | -all |
| ~ softfail | Weak fail | ~all |
| ? neutral | No statement | rare |
Common mechanisms
ip4:203.0.113.0/24— authorize IPv4 rangeip6:2001:db8::/32— authorize IPv6 rangea— authorize A record IPs of current domain (1 lookup)a:mail.example.com— authorize A record of named host (1 lookup)mx— authorize MX host IPs of current domain (1+ lookups)include:spf.protection.outlook.com— delegate to another SPF record (1 lookup + nested)exists:macro— advanced, rare in SMB recordsall— always matches; must be last mechanism
The all mechanism (non-negotiable on sending domains)
-allhard fail: unauthorized IPs should be rejected (use on production senders in 2026)~allsoftfail: weak signal; acceptable only during short migration windows?allneutral: useless for security
+all, you have authorized the entire internet. Remove it immediately.“SPF is a whitelist, not a suggestion. If you forget -all, you never finished the record.”
The 10 Lookup Limit (Where Records Go to Die)
RFC 7208 caps DNS lookups during SPF evaluation at ten. These mechanisms consume lookups:
include:(each one, plus whatever nested includes expand to)a,mx,ptr,exists
Exceeding ten triggers permerror. Receivers treat the SPF result as broken. DMARC fails if you rely on SPF alignment.
Real-world stack that breaks
M365 (include:spf.protection.outlook.com) + Google (include:_spf.google.com) + Mailchimp + HubSpot + Zendesk + Salesforce + legacy ESP + mx + a on the same root domain often crosses ten without looking "too long" in the TXT field.
Fix strategies
- Remove dead includes from retired tools.
- Split mail streams: corporate on root, marketing on
mail.domain.comwith its own SPF and its own 10-lookup budget. - SPF flattening (replace nested includes with IP lists) as last resort with documented maintenance.
Deep dive on permerror: zerohook.org/blog/spf-permerror-too-many-dns-lookups and zerohook.org/fix/spf-permerror
Modifiers: redirect and exp (Rare but Important)
redirect=
Delegates the entire SPF check to another domain's record. Example:
v=spf1 redirect=_spf.example.netThe evaluated domain must have no other mechanisms besides v=spf1 and redirect. Misuse causes permerror. Common on child domains managed by a parent.
exp=
Specifies a domain whose TXT provides an explanation if SPF fails. Almost never needed for SMB mail. If present, it consumes a lookup.
Most production records should use includes and -all, not redirect, unless your DNS architect documented why.
Copy-Paste Templates: Microsoft 365
M365 only (single path)
v=spf1 include:spf.protection.outlook.com -allPublish at root yourdomain.com TXT if all mail flows through Microsoft 365.
M365 + one ESP
v=spf1 include:spf.protection.outlook.com include:servers.mcsv.net -allReplace Mailchimp include with your ESP's documented include host. Count nested lookups before publish.
Common M365 mistakes
- Publishing SPF on the wrong domain (marketing subdomain sends but SPF only on root)
- Forgetting to remove Google's include after migrating off Workspace
- Leaving
~allbecause "it was recommended in 2018"
In Microsoft 365 admin, outbound mail uses Exchange Online IPs covered by spf.protection.outlook.com. Third-party connectors need their own includes.
Copy-Paste Templates: Google Workspace
Google Workspace only
v=spf1 include:_spf.google.com -allGoogle + ESP
v=spf1 include:_spf.google.com include:sendgrid.net -allVerify SendGrid's current include string in their docs; includes change more often than you expect.
Subdomain sending
If marketing sends from news.yourdomain.com, publish a separate SPF on that subdomain. Do not keep stacking includes on root "because it is easier."
Syntax Errors That Cause PermError
- Multiple SPF TXT records on one name. Merge into one.
- Missing v=spf1 or typo
v=spf1with wrong spacing. - Duplicate mechanisms that break parsers on strict receivers (rare but real).
- Empty include: or include pointing at a domain with no SPF.
- Lookup overflow from nested includes (most common in 2026).
- String splitting across multiple TXT strings incorrectly in DNS (some hosts concatenate; some do not).
Validate before and after every change at zerohook.org/spf-checker. Paste the full record in Validate mode, not just dig output with quotes mangled.
SPF vs. DMARC vs. DKIM (One Minute)
| Protocol | Question it answers |
|---|---|
| SPF | Is this IP allowed to use this envelope domain? |
| DKIM | Did someone with the private key sign this message? |
| DMARC | Does the authenticated domain align with the From: header, and what should receivers do on failure? |
SPF syntax mastery does not replace DKIM or DMARC. Gmail and Yahoo bulk sender rules expect all three in 2026. SPF permerror on root can still damage domain reputation even when DKIM passes on a subset of mail.
Frequently Asked Questions
Can I use both ~all and -all?
No. One all mechanism at the end. ~all and -all in the same record is invalid or undefined behavior depending on parser.
Does SPF apply to subdomains automatically?
No. Subdomains need their own TXT unless you use redirect= to a parent policy intentionally. mail.example.com does not inherit example.com SPF.
How fast do SPF changes propagate?
TTL-bound. Many teams see 15 minutes to 4 hours. Do not declare victory at 60 seconds.
Is SPF flattening compliant with audits?
It is a technical control if documented: who maintains IP lists, how updates happen when ESPs rotate IPs, review cadence. Undocumented flattening is a finding waiting to happen.
What is the difference between SPF and TXT for DKIM?
SPF lives on the envelope domain (often root). DKIM publishes on selector._domainkey.domain. Different records, different jobs. Do not merge them.
Key takeaways
One SPF TXT per domain, starting with v=spf1, ending with -all on production senders.
Count every include toward the 10 lookup cap, including nested expansion.
Use provider includes (M365, Google) plus ESP includes only when each path is live and owned.
Split high-volume marketing to subdomains when root SPF gets crowded.
Validate syntax and lookup count before and after every DNS edit.
Paste your record into zerohook.org/spf-checker to catch permerror and lookup overflow before your next DNS change reaches Gmail.
Share this analysis
Help others discover this content
About the author

The ZeroHook Team documents SPF and DKIM misconfigurations that still pass basic lookups but fail at Gmail and Microsoft 365.


