Back to Blog

SPF Record Format: Syntax, Tags, and Practical Examples

9 min read
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 ~all

Read 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

PartExamplePurpose
Versionv=spf1Identifies an SPF version 1 record
Mechanismip4:192.0.2.10Matches a specific IPv4 address
Mechanisminclude:spf.example-sender.netEvaluates another domain’s SPF policy
Mechanismmx or aMatches hosts represented by DNS records
Terminal mechanism-all or ~allHandles senders that did not match earlier terms
Modifierredirect=_spf.example.comDelegates 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:

QualifierResultTypical meaning
+PassAuthorized; this is the default and is usually omitted
-FailNot authorized
~SoftFailProbably not authorized, but do not treat as a hard failure
?NeutralNo policy assertion

Example:

v=spf1 ~include:spf.example-sender.net -all

This 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 -all

Use 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.net

That 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.net

Use 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 -all

Then 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.