SPF Record Syntax Explained: Every Mechanism, Qualifier, and Modifier
By VigilDog Team · August 14, 2026 · 7 min read
An SPF record is a single line of DNS text that decides whether the world's mail servers trust mail claiming to come from your domain — and its syntax is unforgiving. One misplaced qualifier or one lookup too many can flip your mail from "pass" to "fail" without warning. This guide breaks down SPF record syntax completely: every mechanism, every qualifier, every modifier, and the limits that quietly break records that look perfectly fine.
Anatomy of an SPF record
SPF lives in a single TXT record on your domain's root. It always starts with the version tag v=spf1, followed by a space-separated list of mechanisms that describe which servers are allowed to send, and it almost always ends with an all mechanism that decides what happens to everything else. A minimal real-world record looks like this:
v=spf1 include:_spf.google.com ip4:198.51.100.10 ~all
Read left to right, a receiving server checks each mechanism against the connecting IP and stops at the first one that matches. That ordering matters: put ~all or -all at the very end, because it matches everything and anything after it is never evaluated. You are allowed exactly one SPF record per domain — publishing two v=spf1 TXT records is a hard error that produces a PermError and breaks authentication entirely.
Every mechanism, explained
Mechanisms are the building blocks that match a sending IP. These are all of them:
- all — matches everything. Always last; its qualifier sets your default policy.
- ip4 / ip6 — match a specific address or CIDR range, e.g. ip4:198.51.100.0/24. These cost zero DNS lookups.
- a — matches if the connecting IP is an A/AAAA record of the domain (a or a:example.com). One DNS lookup.
- mx — matches the IPs of the domain's MX hosts. One DNS lookup (plus resolution of each MX host).
- include — pulls in another domain's SPF record, e.g. include:_spf.google.com. The workhorse for third-party senders. One lookup each, and nested includes count too.
- exists — matches if a given domain name resolves at all; used for advanced macro-based setups. One lookup.
- ptr — matches via reverse DNS. Officially discouraged by RFC 7208; it's slow and unreliable, so do not use it.
Qualifiers: +, -, ~, and ?
Every mechanism carries a qualifier that says what a match means. Written in front of the mechanism, the four qualifiers are:
- + Pass — the default when you write no qualifier, so a is the same as +a. The IP is authorized.
- - Fail — a hard rejection signal. -all tells receivers to reject anything not already matched.
- ~ SoftFail — a "probably not authorized, but don't reject" signal. ~all is the common safe default while you validate.
- ? Neutral — explicitly no policy. ?all means "make no assertion," which offers almost no protection.
Modifiers: redirect and exp
Modifiers are the two name=value extras that change how the record behaves, and they're often confused with mechanisms. The redirect modifier hands off evaluation entirely to another domain's SPF record — redirect=_spf.example.com — and is used when many domains should share one central policy. Crucially, redirect only takes effect if there is no all mechanism in the record, since all would match first; use one or the other, not both.
The exp modifier points to a TXT record containing a human-readable explanation string that receivers can surface when mail fails SPF. It's purely informational and rarely used in practice. For most domains you'll never need exp, and you'll use redirect only in multi-domain setups — a plain record ending in ~all or -all covers the common case.
The 10-lookup limit that breaks SPF
This is the rule that silently kills records that otherwise look correct. SPF permits a maximum of 10 DNS-querying terms per evaluation. The mechanisms that count are include, a, mx, ptr, exists, and the redirect modifier — and nested includes count too, so one include:_spf.google.com may consume several of your ten. By contrast, ip4, ip6, and all cost nothing, because they need no DNS query.
Exceed 10 lookups and receivers return a PermError, which most treat as an SPF failure — meaning your legitimate mail can start failing the moment you add one more vendor. Every SaaS you add for email (a CRM, a helpdesk, a newsletter tool) tends to want its own include, and domains quietly drift past the limit over months. The fix is usually flattening (replacing includes with the underlying ip4 ranges) or consolidating senders. SPF is also only one of three signals — the diagram below shows how it sits alongside DKIM under DMARC.
Common mistakes and how to validate
The recurring failures are predictable: two SPF records on one domain, a trailing +all that authorizes the entire internet, a ptr mechanism nobody cleaned up, exceeding the 10-lookup limit, or ending in ?all so the record does nothing. Fixing these is the bulk of the work in getting SPF, DKIM, and DMARC right, and it's worth doing before you tighten any policy.
Don't eyeball it — validate. Our free DMARC and email-auth checker parses your SPF record, counts the real DNS lookups, and flags syntax errors and policy gaps. Once SPF and DKIM are solid, SPF alone doesn't stop spoofing; that's DMARC's job, and moving to an enforcing policy is covered in our p=reject rollout guide.
