SPF Record Format: Syntax, Tags, and Practical Examples

An SPF record is a space-separated TXT value. It starts with the version marker v=spf1, contains mechanisms that can match a sending host, and usually ends with an all mechanism that defines the default result.
Example:
v=spf1 ip4:192.0.2.10 include:spf.example-sender.net ~allRead it from left to right. The first mechanism that matches determines the result. The example authorizes one fixed IPv4 address and the provider’s include; every other sender receives SoftFail because of ~all.
Record structure
| Part | Example | Purpose |
|---|---|---|
| Version | v=spf1 | Identifies an SPF version 1 record |
| Mechanism | ip4:192.0.2.10 | Matches a specific IPv4 address |
| Mechanism | include:spf.example-sender.net | Evaluates another domain’s SPF policy |
| Mechanism | mx or a | Matches hosts represented by DNS records |
| Terminal mechanism | -all or ~all | Handles senders that did not match earlier terms |
| Modifier | redirect=_spf.example.com | Delegates evaluation when no mechanism matches |
The terms do not use commas. A DNS provider may show a long TXT value in multiple quoted strings, but it is still one logical SPF record.
Qualifiers
A mechanism can have a qualifier before it:
| Qualifier | Result | Typical meaning |
|---|---|---|
| + | Pass | Authorized; this is the default and is usually omitted |
| - | Fail | Not authorized |
| ~ | SoftFail | Probably not authorized, but do not treat as a hard failure |
| ? | Neutral | No policy assertion |
Example:
v=spf1 ~include:spf.example-sender.net -allThis record is unusual because a matching include returns SoftFail while unmatched senders return Fail. Prefer a clear policy that reflects your migration stage rather than adding qualifiers without a reason.
Mechanisms that matter most
include
Include evaluates the referenced domain’s SPF policy. It is the normal way to authorize a managed email provider. The referenced policy can contain more includes, so the full chain counts toward the lookup budget.
ip4 and ip6
These authorize an IP address or network without a DNS lookup during SPF evaluation:
v=spf1 ip4:192.0.2.10 ip6:2001:db8::/32 -allUse only addresses that are actually used by your sending infrastructure.
a and mx
These match addresses returned by the domain’s A/AAAA or MX records. They cause DNS lookups and can authorize more hosts than you intended. Use them only when the domain’s mail infrastructure is also the sending infrastructure.
all
The all mechanism always matches, so it belongs at the end. Putting it before an include makes the later include unreachable:
v=spf1 -all include:spf.example-sender.netThat record rejects before it reaches the provider. It is syntactically readable but operationally wrong.
redirect
Redirect supplies another SPF policy when no mechanism in the current record matches. It is a modifier, not a mechanism, and it is most useful when several domains intentionally share one policy. For a small sender inventory, one direct record is easier to maintain.
The lookup budget
RFC 7208 limits DNS-querying terms to ten during evaluation. Include, a, mx, ptr, exists, and redirect consume the budget; ip4, ip6, and all do not. If a receiver exceeds the limit, SPF can return a permanent error.
Querying the visible record is not enough because includes can be nested:
dig +short TXT example.com
dig +short TXT spf.example-sender.netUse a validator that expands the chain and reports the count. Remove obsolete providers before trying to optimize a live record.
One SPF record per domain
If DNS returns multiple values beginning with v=spf1, the receiver cannot reliably choose one. Merge the mechanisms into one record:
v=spf1 include:spf.example-sender.net include:spf.example-crm.net -allThen verify that both providers still need authorization and that their nested lookups fit the budget.
SPF is only one authentication path
SPF evaluates the envelope sender, not the visible From address. DMARC requires an aligned SPF or DKIM result, so a passing SPF result can still fail DMARC alignment.
For Gmail recipients, follow the current sender authentication guidance and inspect real message headers after DNS changes.
FAQ
Is v=spf1 a tag?
It is the version declaration at the start of the record. It is required for an SPF record to be recognized as SPF.
Can I split an SPF record into two TXT records?
No. Long TXT values can be represented as multiple quoted strings inside one DNS record, but publishing two separate SPF records is invalid.
Should the record end with -all?
Use -all only after you have inventoried legitimate senders. During a controlled migration, ~all may provide a softer transition, but it should not become a permanent excuse for an unknown sender inventory.
Why did my include not authorize mail?
Check the envelope-from domain, the exact provider include, nested lookup errors, duplicate SPF records, and the message’s SPF result. A provider dashboard may be verifying a different domain than the message uses.
Use the SPF record examples for copyable setup patterns.