SPF record syntax explained: mechanisms and qualifiers

An SPF record is a single DNS TXT record that lists which servers may send mail for your domain. It always starts with v=spf1, followed by one or more mechanisms (which match the sending server) and ends with an all mechanism (the catch-all for everything else). Each mechanism can carry a qualifier — + pass, - fail, ~ softfail, or ? neutral — that tells the receiver what to do when it matches. A receiving server reads the record left to right and stops at the first mechanism that matches the connecting IP.
Quick Takeaways
- Every SPF record begins with the version tag
v=spf1and lives in one TXT record at the domain root. - Mechanisms (
a,mx,ip4,ip6,include,all) define which servers are authorized. - Qualifiers set the result:
+pass (default),-fail,~softfail,?neutral. - Records evaluate left to right and stop at the first match, so order matters.
include,a,mx,ptr, andexistseach cost DNS lookups; the total is capped at 10.- End with
~all(softfail) or-all(hardfail) — never+all, which authorizes the entire internet.
What does an SPF record look like?
A complete record is one line of space-separated terms. Here is a typical example for a domain that sends through Google Workspace plus one third-party service:
v=spf1 include:_spf.google.com include:sendgrid.net ip4:198.51.100.25 ~all
Reading it left to right: the version tag declares SPF v1; the two include mechanisms pull in Google's and the service's authorized IP ranges; the ip4 mechanism authorizes one specific address; and ~all softfails everything else. The full grammar is defined in RFC 7208, the SPF standard.
| Part | Term | Meaning |
|---|---|---|
| Version | v=spf1 | Required first term; marks this as an SPF record |
| Mechanism | include:_spf.google.com | Authorize the IPs in Google's SPF record |
| Mechanism | ip4:198.51.100.25 | Authorize this exact IPv4 address |
| Qualifier + all | ~all | Softfail any sender not matched above |
What are SPF mechanisms?
Mechanisms are the building blocks that match the connecting server against your policy. When a mechanism matches the sending IP, evaluation stops and the mechanism's qualifier decides the result.
| Mechanism | Matches when | Costs a DNS lookup? |
|---|---|---|
all | Always — the catch-all, placed last | No |
ip4: | The sender's IPv4 address (or CIDR range) matches | No |
ip6: | The sender's IPv6 address (or range) matches | No |
a | The sender's IP matches an A/AAAA record of the domain | Yes |
mx | The sender's IP matches one of the domain's MX hosts | Yes |
include: | The included domain's SPF record passes | Yes |
exists: | A constructed domain name resolves (advanced macros) | Yes |
ptr | The sender's reverse DNS matches (deprecated — avoid) | Yes |
The three you will use most are include, ip4, and all. Most providers give you an include to add — that is how Google Workspace, Microsoft 365, and services like Mailgun and HubSpot publish their sending ranges without you having to list individual IPs. Use ip4/ip6 for your own fixed mail servers, and reserve ptr for never: it is slow, unreliable, and RFC 7208 explicitly discourages it.
What are SPF qualifiers?
A qualifier is the single character in front of a mechanism that sets the result when that mechanism matches. If you write no qualifier, the default is + (pass).
| Qualifier | Name | Result when matched | Typical use |
|---|---|---|---|
+ | Pass | Authorized — accept | Default; rarely written explicitly |
- | Fail | Not authorized — reject | -all for a strict, locked-down policy |
~ | Softfail | Suspicious — accept but mark | ~all, the common safe default |
? | Neutral | No policy — treat as none | Testing, or genuinely unknown senders |
In practice, qualifiers matter most on the final all mechanism, because that is what decides the fate of every server you did not list:
~all(softfail) — the pragmatic default. Unlisted senders are accepted but flagged, so a missed legitimate source doesn't get bounced while you finish tightening your setup.-all(hardfail) — the strict option. Unlisted senders are rejected outright. Move here once you are confident every legitimate source is in the record. Our guide to softfail versus hardfail walks through the trade-off.+all— never use this. It tells receivers that any server on the internet is authorized to send as your domain, which defeats the entire purpose of SPF.
How does a receiver evaluate an SPF record?
The receiving server walks the mechanisms from left to right and stops at the first one that matches the connecting IP. That first match's qualifier is the final result — later mechanisms are never checked. This is why order matters and why all must come last: anything after all is unreachable.
The possible results are pass, fail, softfail, neutral, plus three that come from problems rather than matches:
none— the domain has no SPF record at all.permerror— the record is malformed or exceeds the 10-lookup limit (below).temperror— a transient DNS failure; the receiver may retry.
pass alone is not the finish line. For DMARC to pass on SPF, the domain that SPF authenticated (the envelope Return-Path) must also align with the domain in the visible From header. That is why sending through a subdomain and keeping relaxed alignment matters — SPF can pass yet still fail DMARC if the domains don't line up. You can confirm both the syntax and the result on a live domain with Palisade's SPF checker.
Why does SPF have a 10-lookup limit?
To stop a single message from triggering an unbounded chain of DNS queries, RFC 7208 caps an SPF evaluation at 10 DNS-querying mechanisms. The mechanisms that count are include, a, mx, ptr, and exists — and crucially, every include counts the lookups inside the record it pulls in, recursively. ip4, ip6, and all cost nothing because they need no DNS query.
Exceed 10 and the whole record returns permerror, which most receivers treat as an SPF failure — so a record meant to protect you starts breaking your legitimate mail. It is a common failure once a domain adds a few includes, because a single provider's include can hide four or five nested lookups.
Ways to stay under the limit:
- Replace
includes withip4/ip6where a provider publishes stable IPs — flattening trades DNS lookups for a longer static record. - Remove services you no longer use. Old
includes from a decommissioned newsletter tool are pure waste. - Consolidate senders onto fewer platforms or subdomains so each domain's SPF stays lean.
include is pushing you over, and the Email Security Score rolls SPF, DKIM, and DMARC into one health check — useful when you manage records across many client domains and need to catch a permerror before receivers do.
Common issues with SPF syntax
The record returns permerror
Almost always the 10-lookup limit or a typo. Count the DNS-querying mechanisms (include, a, mx, ptr, exists), remembering nested includes, and flatten or trim until you are under 10. A stray character — a smart quote pasted from a document, or a missing space between mechanisms — will also throw permerror.
There are two SPF records on the domain
A domain may publish only one SPF record. Two v=spf1 TXT records don't combine — they produce a permerror and invalidate each other. Merge every mechanism into a single record: keep one v=spf1, list all the includes and IPs, and end with a single all.
~all was placed in the middle of the record
Because evaluation stops at the first match, an all anywhere but the end short-circuits every mechanism after it. all — with whatever qualifier — must be the final term.
A subdomain has no SPF record
SPF does not inherit down subdomains. A parent domain's record does not cover mail.example.com unless that subdomain publishes its own. If a sending subdomain has no record, its mail evaluates to none. Publish an SPF record on each sending subdomain.
Frequently asked questions
Should I end my SPF record with ~all or -all?
Use ~all (softfail) while you are still identifying every legitimate sender, then move to -all (hardfail) once the record is complete and you have confirmed nothing legitimate is being missed. -all gives the strongest protection because receivers reject unlisted senders outright, but jumping there too early risks bouncing your own mail.
Do SPF mechanisms and qualifiers care about case?
No. v=spf1, mechanism names, and qualifiers are case-insensitive, so Include: and include: behave identically. The domain names and IP addresses inside them follow normal DNS rules. Write everything lowercase by convention for readability.
What's the difference between include and redirect?
include: brings another domain's authorized senders into your policy while your own all still decides the final result. redirect= hands the entire evaluation to another domain's SPF record — your record's all is ignored. Use include for adding a service; use redirect only when you deliberately want one domain's SPF policy to govern several domains.
Does a longer SPF record hurt deliverability?
Length itself is fine as long as you stay within the 10-lookup limit and the 255-character-per-string TXT format (longer values are split into multiple quoted strings). What hurts deliverability is a permerror from too many lookups or a duplicate record, because receivers then can't authenticate you at all. Keep the record lean and validate it with an SPF checker.
Related reading

Written by
Samuel ChenardCEO & Co-Founder, Palisade
Samuel Chenard is the CEO and co-founder of Palisade, the DMARC automation platform for MSPs. He writes Palisade's guides on DMARC, SPF, DKIM and email deliverability.
More from Samuel →


