SPF Record Syntax: A Complete Reference Guide

Diagram explaining SPF record syntax components and structure

SPF records can look cryptic at first glance. A string like v=spf1 include:_spf.google.com ip4:192.168.1.1 ~all contains a lot of meaning packed into a short format. Understanding this syntax is essential for building effective SPF records and troubleshooting authentication issues.

This reference guide breaks down every component of SPF record syntax with practical examples you can apply to your own domain.

SPF Record Structure

Every SPF record follows this basic structure:

v=spf1 [mechanisms] [modifiers]

Let's examine each component.

The Version Tag

v=spf1

Every SPF record must start with this version identifier. It tells email receivers this is an SPF version 1 record. There is no SPF version 2—despite the name, the "Sender ID" proposal (sometimes called SPFv2) never became widely adopted.

Important: This must be the very first thing in the record. No spaces before it.

Qualifiers

Qualifiers appear before mechanisms and determine what happens when a mechanism matches. There are four qualifiers:

Qualifier Symbol Result Meaning
Pass + Pass This source is authorized (default if no qualifier)
Fail - Fail This source is NOT authorized—reject
SoftFail ~ SoftFail This source is probably not authorized—accept but mark
Neutral ? Neutral No assertion—treat as if no SPF exists

If no qualifier is specified, + (Pass) is assumed. So ip4:192.168.1.1 is the same as +ip4:192.168.1.1.

Mechanisms

Mechanisms are the core of SPF—they define which servers are authorized to send email for your domain.

all

Matches everything. Used at the end of a record to define the default action.

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

Common usage patterns:

  • -all — Reject anything not explicitly authorized (hardfail)
  • ~all — Accept but mark as suspicious (softfail)
  • ?all — Neutral, no default policy
  • +all — Allow anyone (never use this—it defeats the purpose of SPF)

ip4

Matches a specific IPv4 address or range.

ip4:192.168.1.1          (single IP)
ip4:192.168.1.0/24       (CIDR range - 256 IPs)

Use this when you know the exact IP addresses of your mail servers.

ip6

Matches a specific IPv6 address or range.

ip6:2001:db8::1                    (single IP)
ip6:2001:db8::/32                  (CIDR range)

a

Matches the A record (IPv4) or AAAA record (IPv6) of a domain.

a                     (matches your domain's A record)
a:mail.example.com    (matches that domain's A record)
a/24                  (matches your domain's A record with /24 CIDR)

Useful when your web server and mail server share an IP, or when a server's IP might change but its hostname won't.

mx

Matches the IP addresses of your domain's MX (mail exchange) records.

mx                    (your domain's MX servers)
mx:example.com        (that domain's MX servers)
mx/24                 (your MX servers with /24 CIDR)

Common for domains where inbound and outbound mail use the same servers.

include

Includes another domain's SPF record. This is how you authorize third-party email services.

include:_spf.google.com        (Google Workspace)
include:servers.mcsv.net       (Mailchimp)
include:sendgrid.net           (SendGrid)
include:spf.protection.outlook.com    (Microsoft 365)

Important: Each include counts toward your 10 DNS lookup limit. The included domain's SPF may also contain more includes, which also count.

exists

Matches if a specific domain exists in DNS (regardless of what it resolves to).

exists:%{i}._spf.example.com

Advanced mechanism used for per-IP authorization or macro-based lookups. Rarely needed for typical configurations.

ptr (Deprecated)

Matches based on reverse DNS lookup. Do not use.

ptr                   (deprecated)
ptr:example.com       (deprecated)

This mechanism is deprecated in RFC 7208 because it's slow, unreliable, and causes excessive DNS queries. Modern SPF validators may ignore it.

Modifiers

Modifiers provide additional information but don't directly authorize senders.

redirect

Replaces the current SPF evaluation with another domain's SPF record.

v=spf1 redirect=_spf.example.com

Key difference from include:

  • include — If the included record doesn't match, continue evaluating
  • redirect — Completely replace this record with the target's SPF

Use redirect when a domain's entire SPF policy should be defined elsewhere (like for subdomains or aliased domains).

exp

Specifies a domain containing an explanation message for failures.

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

The TXT record at the explanation domain contains a human-readable message about why the email failed. Rarely used in practice.

Practical Examples

Google Workspace Only

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

Microsoft 365 Only

v=spf1 include:spf.protection.outlook.com -all

Multiple Services

v=spf1 include:_spf.google.com include:servers.mcsv.net include:sendgrid.net -all

Own Mail Server Plus Services

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

Subdomain with Redirect

For a subdomain that should use the parent domain's SPF:

v=spf1 redirect=example.com

No Email from This Domain

For domains that should never send email:

v=spf1 -all

Macros (Advanced)

SPF supports macros for dynamic lookups. These are rarely needed but powerful for complex configurations.

Macro Meaning
%{s} Sender (the MAIL FROM address)
%{l} Local part of sender (before the @)
%{o} Domain of sender
%{d} Domain being checked
%{i} IP address of connecting server
%{h} HELO/EHLO domain
%{v} IP version (in4 or in6)

Example using macro for per-IP lookup:

v=spf1 exists:%{i}._spf.example.com -all

This checks if a DNS record exists for each connecting IP, allowing granular per-IP authorization.

Common Syntax Errors

Missing Version Tag

include:_spf.google.com -all

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

Multiple SPF Records

You can only have one SPF record per domain. Multiple records cause failures.

❌ Two separate TXT records
✅ One record with all mechanisms combined

Missing all Mechanism

Without an all at the end, there's no default policy.

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

Using +all

Never use +all—it allows anyone to send as your domain.

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

Exceeding 10 DNS Lookups

The 10 DNS lookup limit includes all include, a, mx, ptr, and redirect mechanisms (including nested lookups).

Testing Your SPF Record

Before publishing, validate your SPF syntax with these tools:

  • MxToolbox SPF Checker — Validates syntax and counts lookups
  • Google Admin Toolbox — Check MX and SPF records
  • SPF Record Testing Tools — Many free options available online

Related Resources

0 comments

Leave a comment

Please note, comments need to be approved before they are published.