Quick Answer

SPF record syntax: v=spf1 (required version tag) + mechanisms (include:, ip4:, ip6:, a, mx) that define authorized senders + a qualifier (-all, ~all) that defines the default action. include: authorizes another domain's SPF (for ESPs). ip4:/ip6: authorizes specific IPs (don't count toward 10-lookup limit). a/mx authorize your domain's A/MX record IPs. -all = hard fail unauthorized. ~all = soft fail. Always end with -all for production.

SPF Record Syntax Explained: Mechanisms, Qualifiers, and Modifiers

By Braedon·Mailflow Authority·Email Authentication·Updated 2026-03-31

SPF Record Structure

v=spf1 [mechanisms] [qualifier]

Every SPF record starts with v=spf1 and ends with a qualifier (-all, ~all, etc.).

Mechanisms

include:

Authorizes another domain's SPF record. Used for ESP services.

include:_spf.google.com    → Authorizes Google Workspace
include:sendgrid.net       → Authorizes SendGrid
include:mailgun.org        → Authorizes Mailgun
include:_spf.klaviyo.com   → Authorizes Klaviyo
include:spf.hubspot.com    → Authorizes HubSpot

Lookup cost: 1+ per include (the included record may chain to sub-includes).

ip4: / ip6:

Authorizes specific IP addresses.

ip4:203.0.113.5      → Authorizes one IPv4
ip4:203.0.113.0/24   → Authorizes an IPv4 range (CIDR notation)
ip6:2001:db8::1      → Authorizes one IPv6

Lookup cost: 0 (no DNS query needed). Use for your own servers.

a

Authorizes the IP addresses in your domain's A record(s).

a                → Authorizes IPs from yourdomain.com's A record
a:mail.example.com → Authorizes IPs from mail.example.com's A record

Lookup cost: 1 per a mechanism.

mx

Authorizes the IP addresses of your domain's MX servers.

mx               → Authorizes your MX server IPs
mx:example.com   → Authorizes example.com's MX IPs

Lookup cost: 1+ (MX lookup + A lookups for each MX hostname).

exists:

Advanced. Checks if a specific domain resolves. Used for macros and complex policies.

exists:%{i}.spf.example.com → Dynamic IP-based check

Lookup cost: 1. Rarely needed for standard configurations.

Qualifiers

The qualifier at the end defines the default policy for IPs not matched by any mechanism:

QualifierMeaningEffect
-allHard failUnauthorized = reject
~allSoft failUnauthorized = suspicious (may deliver)
?allNeutralNo policy (useless)
+allPass allEveryone authorized (NEVER use this)

Use -all for production. It provides the strongest protection. ~all is acceptable during initial testing.

Modifiers

redirect=

Replaces your SPF with another domain's.

v=spf1 redirect=_spf.example.com

"Don't evaluate my record — use example.com's instead."

Cannot be combined with other mechanisms. Only one redirect per record.

exp=

Provides an explanation for failures (custom error message).

v=spf1 include:_spf.google.com -all exp=explain.yourdomain.com

The explain.yourdomain.com TXT record contains a human-readable explanation. Rarely used in practice.

Complete Examples

Simple (one ESP):

v=spf1 include:_spf.google.com -all

Moderate (ESP + transactional + self-hosted):

v=spf1 include:_spf.google.com include:sendgrid.net ip4:203.0.113.10 -all

Complex (multiple services):

v=spf1 include:_spf.google.com include:sendgrid.net include:mailgun.org include:_spf.klaviyo.com -all

⚠ Check lookup count before deploying.

Validation

After creating or modifying your SPF record:

  1. MXToolbox SPF Lookup: Enter your domain → shows record, lookup count, errors
  2. Count lookups: Must be ≤ 10
  3. Check for duplicates: Only ONE SPF TXT record per domain
  4. Verify syntax: No extra spaces, correct mechanism names, ends with -all or ~all

Practitioner note: The redirect= modifier is underused. For organizations managing 10+ domains with the same sending services, publish one master SPF record and redirect all domains to it. When you add or remove a service, update one record instead of ten.

Practitioner note: Never use +all. I've seen it on production domains where someone "temporarily" set it for testing and forgot to revert. +all means "any server on the internet is authorized to send as my domain." It completely defeats SPF.

For common SPF configurations, see SPF record examples. For the complete setup process, see the SPF setup guide. For understanding the 10 DNS lookup limit, see our dedicated guide. If you need SPF records designed for complex multi-service setups, schedule a consultation.

Sources


v1.0 · March 2026

Frequently Asked Questions

What's the difference between include and ip4?

include: references another domain's SPF record (e.g., include:sendgrid.net pulls in all of SendGrid's IPs). Costs DNS lookups. ip4: directly lists an IP address. No lookup cost. Use include: for ESP services (their IPs change). Use ip4: for your own static servers.

What's the difference between -all and ~all?

-all (hardfail): unauthorized senders are rejected. Strongest protection. ~all (softfail): unauthorized senders are marked suspicious but may still deliver. Weaker. Google recommends starting with ~all and moving to -all once verified. I recommend -all for production.

What does 'redirect' do in SPF?

redirect= replaces your entire SPF record with another domain's SPF. Example: v=spf1 redirect=_spf.example.com means 'use example.com's SPF instead of mine.' Useful for organizations managing multiple domains with one SPF policy. Different from include: (which adds to your policy).

Do ip4 and ip6 mechanisms count toward the 10-lookup limit?

No. ip4: and ip6: are evaluated locally without DNS queries. They don't count toward the 10-lookup limit. This is why SPF flattening (replacing includes with IPs) solves the lookup limit problem.

Can I use multiple include: mechanisms?

Yes, as many as you need — BUT each costs DNS lookups. Each include: costs 1 lookup minimum, and the included record may chain to more lookups. Total across all includes must stay under 10. Merge multiple services into one SPF record.

Want this handled for you?

Free 30-minute strategy call. Walk away with a plan either way.