Skip to main content
New SPF lookups must resolve in milliseconds — why a DMARC tool's add-on isn't enough Learn Why → →
Foundational 15 min read

SPF Record Syntax Explained: The Complete Guide to Mechanisms, Qualifiers, and Limits

Brad Slavin
Brad Slavin General Manager

Quick Answer

An SPF record is a DNS TXT record that begins with v=spf1 and contains a series of mechanisms and qualifiers that define which servers are authorized to send email for a domain. Mechanisms include ip4, ip6, a, mx, include, exists, redirect, and all. Each mechanism can be prefixed with a qualifier: + (pass, the default), - (fail), ~ (softfail), or ? (neutral). SPF evaluation is limited to 10 DNS mechanism lookups per check and 2 void lookups. The record must be a single TXT entry and should stay under 512 bytes to avoid DNS truncation.

Try Our Free SPF Checker

Instantly analyze any domain's SPF record - check syntax, count DNS lookups, and flag errors.

Check SPF Record →

SPF record syntax is the foundation of email authentication. Every mechanism, qualifier, and modifier in an SPF record has precise meaning defined by RFC 7208, and even small deviations from the specification can cause legitimate email to fail authentication or - worse - leave your domain unprotected against spoofing.

This guide covers every element of SPF syntax in detail, explains how the evaluation engine processes each mechanism, and links to focused articles on specific topics for deeper exploration.

The Anatomy of an SPF Record

Every SPF record is a DNS TXT record that follows this structure:

v=spf1 [qualifier][mechanism] [qualifier][mechanism] ... [qualifier]all

Here is a real-world example:

v=spf1 ip4:198.51.100.0/24 include:_spf.google.com include:sendgrid.net -all

Let’s break this down:

ElementMeaning
v=spf1Version declaration - must be the first token
ip4:198.51.100.0/24Authorize this IP range (no DNS lookup required)
include:_spf.google.comInclude Google Workspace’s SPF policy (1 DNS lookup)
include:sendgrid.netInclude SendGrid’s SPF policy (1 DNS lookup)
-allHard fail - reject any sender not matched above

For a broader introduction to the protocol, see What is SPF? A Detailed Guide on Sender Policy Framework.

The Version Tag: v=spf1

Every SPF record must begin with v=spf1. This is not optional. A TXT record that does not start with this exact string (case-sensitive) is not an SPF record and will be ignored during SPF evaluation.

Common mistakes:

  • v=spf 1 - Space between “spf” and “1” invalidates the record
  • v=SPF1 - Uppercase is technically invalid per the RFC, though some implementations tolerate it
  • Omitting v=spf1 entirely - The record is not recognized as SPF

Mechanisms

Mechanisms are the core of an SPF record. They define the rules for matching a sender’s IP address against the list of authorized senders. Mechanisms are evaluated left to right, and evaluation stops at the first match.

ip4 and ip6

The ip4 and ip6 mechanisms match against specific IP addresses or CIDR ranges. They are the most straightforward mechanisms and do not consume DNS lookups.

v=spf1 ip4:203.0.113.5 ip4:198.51.100.0/24 ip6:2001:db8::/32 -all
  • ip4:203.0.113.5 - Matches a single IPv4 address
  • ip4:198.51.100.0/24 - Matches a /24 CIDR range (256 addresses)
  • ip6:2001:db8::/32 - Matches an IPv6 CIDR range

Best practice: Use ip4 and ip6 for servers you control directly. They are precise, do not consume DNS lookups, and do not depend on third-party DNS availability.

Gotcha: Using incorrect CIDR notation is a common syntax error. See How Does the CIDR Notation Error Affect SPF? for details.

include

The include mechanism delegates SPF evaluation to another domain’s SPF record. It is the standard way to authorize third-party email services.

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

When the evaluator reaches an include, it fetches the SPF record for the specified domain and evaluates it against the sender’s IP. If the included record returns Pass, the include matches. If it returns Fail, SoftFail, or Neutral, the include does not match and evaluation continues to the next mechanism.

Each include consumes at least 1 DNS lookup, and the included record may itself contain additional mechanisms that consume more lookups. This cascading effect is the primary reason records exceed the 10-lookup limit.

Detailed guides:

a

The a mechanism matches if the sender’s IP is one of the A (or AAAA) records for the specified domain. If no domain is specified, it defaults to the current domain.

v=spf1 a a:mail.example.com -all
  • a - Matches if the sender IP is an A record for the current domain
  • a:mail.example.com - Matches if the sender IP is an A record for mail.example.com

Consumes 1 DNS lookup. Use sparingly if you are close to the 10-lookup limit.

mx

The mx mechanism matches if the sender’s IP is one of the MX hosts for the specified domain. The evaluator resolves the MX records, then resolves each MX hostname to its A/AAAA records, and checks against the sender’s IP.

v=spf1 mx mx:backup.example.com -all

Consumes 1 DNS lookup (plus additional lookups for A/AAAA resolution of each MX host). The RFC limits MX evaluation to 10 MX records per mechanism.

Note: For most modern configurations, explicitly listing IPs with ip4/ip6 is preferred over using mx, which adds unnecessary lookup overhead.

exists

The exists mechanism checks whether an A record exists for the specified domain. It does not match against the IP address itself - it only checks for the existence of the DNS record. This mechanism is primarily used in combination with macros for advanced use cases.

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

In this example, %{i} is a macro that expands to the sender’s IP address. The evaluator checks whether an A record exists for 192.0.2.1.spf.example.com (for example). This allows whitelisting individual IPs via DNS without listing them in the SPF record itself.

Consumes 1 DNS lookup.

ptr (Deprecated)

The ptr mechanism performs a reverse DNS lookup on the sender’s IP and checks whether the resulting hostname resolves back to the sender’s IP and falls within the specified domain. This mechanism is strongly discouraged by RFC 7208 due to performance issues (it requires multiple DNS lookups) and unreliable reverse DNS data.

Detailed guide: Reasons Behind Discouraging the Use of PTR Mechanism in an SPF Record

all

The all mechanism matches everything. It is always the last mechanism in an SPF record and defines the default action for senders that did not match any previous mechanism.

  • -all - Hard fail. Senders not listed should be rejected.
  • ~all - Soft fail. Senders not listed are suspicious but should not be rejected outright. Often used during initial SPF deployment.
  • ?all - Neutral. No assertion is made about unlisted senders.
  • +all - Pass. All senders are authorized. This effectively disables SPF and should never be used.

Detailed guides:

Qualifiers

Every mechanism can be prefixed with a qualifier that determines the result if the mechanism matches:

QualifierResultMeaning
+PassThe sender is authorized (default if no qualifier is specified)
-FailThe sender is explicitly not authorized
~SoftFailThe sender is probably not authorized, but don’t hard reject
?NeutralNo assertion - equivalent to no SPF at all for this mechanism

The qualifier applies to the mechanism it precedes. For example, ~include:thirdparty.com means that if the included record does not match, the result is SoftFail rather than the default behavior.

In practice, qualifiers are almost exclusively used on the all mechanism. Using qualifiers on other mechanisms is syntactically valid but uncommon and can create confusing evaluation behavior.

Modifiers

Modifiers are name/value pairs that provide additional processing instructions. Unlike mechanisms, modifiers do not directly match against IP addresses.

redirect

The redirect modifier replaces the current domain’s SPF evaluation with another domain’s SPF record. It is processed only if no mechanism in the record matches. Unlike include, which only adopts the Pass result, redirect adopts whatever result the target record produces.

v=spf1 redirect=_spf.example.com

Consumes 1 DNS lookup. The redirect modifier should not be combined with all - if an all mechanism is present, the redirect is never reached.

exp

The exp modifier specifies a domain whose TXT record contains an explanation string to be included in bounce messages when SPF fails. It is rarely used in practice.

v=spf1 ip4:203.0.113.0/24 -all exp=spf-explanation.example.com

The 10-DNS-Lookup Limit

This is the single most impactful technical constraint in SPF. RFC 7208 Section 4.6.4 limits SPF evaluation to 10 DNS mechanism lookups per check.

What Counts as a DNS Lookup

Mechanism/ModifierCounts as DNS Lookup?
ip4No
ip6No
allNo
includeYes (1 per include, plus any nested lookups)
aYes
mxYes
ptrYes
existsYes
redirectYes

What Happens When You Exceed the Limit

When the 10th DNS lookup is reached, evaluation stops immediately. Any remaining mechanisms are not evaluated. The SPF result is PermError, which means every subsequent message from the domain fails SPF.

This is not a warning or a soft limit. It is a hard stop.

Strategies for Staying Within the Limit

  1. Replace a and mx with ip4/ip6 - If you know the IPs, use them directly
  2. Remove unused includes - Audit your record quarterly and remove services you no longer use
  3. Use SPF flattening - Resolve includes to IP addresses. AutoSPF does this dynamically.
  4. Use SPF macros - Advanced technique that can authorize senders without additional DNS lookups. See Automating SPF Macro Management.
  5. Delegate to subdomains - Separate sending domains for marketing, transactional, and corporate email. See How to Set Up SPF Records for Subdomains.

Detailed guides:

The Void Lookup Limit

In addition to the 10-DNS-lookup limit, RFC 7208 also limits void lookups to 2 per evaluation. A void lookup occurs when a DNS query returns either NXDOMAIN (the domain does not exist) or an empty answer (NOERROR with no records). Exceeding this limit also produces a PermError.

This limit is designed to prevent SPF records from being used as a vector for DNS amplification attacks.

Character and Size Limits

255-Character String Limit

DNS TXT records are technically limited to 255 characters per string within a single record. SPF records longer than 255 characters must be split into multiple strings that are concatenated during processing. Most DNS providers handle this automatically, but some require manual splitting.

512-Byte UDP Response Limit

DNS responses over UDP are traditionally limited to 512 bytes. If an SPF record (including DNS overhead) exceeds this limit, the response may be truncated, causing the client to retry over TCP. While most modern resolvers handle this gracefully, it can introduce latency and occasional failures.

Detailed guide: How the SPF Record Character Limit Affects Your Email Authentication

SPF Macros

SPF macros are placeholder variables that are expanded during evaluation. They allow dynamic SPF records that adapt based on the sender’s IP, domain, or other parameters.

MacroExpands To
%{s}Sender (MAIL FROM address)
%{l}Local part of sender
%{o}Domain of sender
%{d}Current domain being evaluated
%{i}Sender’s IP address
%{h}HELO/EHLO domain

Macros are most commonly used with the exists mechanism to create per-IP authorization lookups without consuming multiple include-based DNS lookups.

Detailed guide: Automating SPF Macro Management with Scripting and APIs

SPF Evaluation Order and Processing

Understanding how SPF records are evaluated is essential for building effective records. Mechanisms are processed strictly left to right. When a mechanism matches the sender’s IP, evaluation stops immediately and the mechanism’s qualifier determines the result.

This means the order of mechanisms matters:

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

In this example, if the sender’s IP is 192.0.2.5, the first mechanism matches with a - (fail) qualifier, and the message fails SPF - even though _spf.google.com might also authorize that IP. The include is never evaluated.

In practice, you almost never need to use negative qualifiers on individual mechanisms. The all mechanism at the end handles the default case. The evaluation-stops-on-first-match behavior is more relevant when you need to understand why a particular IP passes or fails.

What Happens When No Mechanism Matches

If no mechanism in the record matches the sender’s IP and no all mechanism is present, the default result is Neutral. If a redirect modifier is present, evaluation continues with the target domain’s SPF record. If neither all nor redirect is present, the result is Neutral - equivalent to the domain making no assertion about the sender.

Nested Include Depth

When an include mechanism is encountered, the evaluator fetches the target domain’s SPF record and evaluates it recursively. The included record may itself contain include mechanisms, creating nested lookups. All of these count toward the 10-DNS-lookup limit. There is no separate limit on nesting depth, but the 10-lookup limit effectively constrains it.

For example, if include:_spf.google.com resolves to a record that itself contains 3 includes, your record has consumed 4 lookups (1 for the initial include plus 3 for the nested includes).

SPF Record Types and Variations

There are several common patterns for structuring SPF records depending on your infrastructure:

  • Simple single-provider - v=spf1 include:_spf.google.com -all
  • Multi-provider with IP ranges - v=spf1 ip4:x.x.x.x include:provider.com -all
  • Subdomain delegation - Different SPF records for different subdomains
  • Macro-based - Dynamic authorization using the exists mechanism
  • Redirect-based - Centralized SPF management via redirect

Detailed guide: Complete Guide to SPF Record Types: 6 Variations Explained

Common Syntax Mistakes

These are the most frequently encountered syntax errors that break SPF records:

  1. Multiple SPF records - Publishing two TXT records starting with v=spf1 on the same domain
  2. Missing v=spf1 - The record is not recognized as SPF without it
  3. Using +all - Authorizes every sender, defeating the purpose of SPF
  4. Typos in include domains - include:_spf.goggle.com instead of include:_spf.google.com
  5. Spaces in the wrong places - v=spf 1 instead of v=spf1
  6. Using deprecated Type 99 records - SPF records must be TXT records, not the deprecated SPF record type
  7. Incorrect CIDR notation - /33 or higher for IPv4, /129 or higher for IPv6

Detailed guides:

Tools for Working with SPF Syntax

  • SPF Record Generator - Build a syntactically correct SPF record by selecting your sending services
  • SPF Checker - Validate an existing record for syntax errors and lookup count
  • SPF Validator - Full evaluation with mechanism-by-mechanism breakdown
  • SPF Record Lookup - Raw DNS lookup of your published SPF record

SPF in the Context of Email Authentication

SPF is one component of a three-protocol email authentication stack:

  • SPF defines which servers can send email for your domain (this guide)
  • DKIM adds a cryptographic signature to verify message integrity and origin
  • DMARC ties SPF and DKIM together with alignment requirements and reporting

Understanding SPF syntax is essential, but it is not sufficient on its own. For complete email authentication, you need all three protocols configured and aligned. See How SPF Differs from DKIM and DMARC for a detailed comparison.

Brad Slavin
Brad Slavin

General Manager

Founder and General Manager of DuoCircle. Product strategy and commercial lead for AutoSPF's 2,000+ customer base.

LinkedIn Profile →

Ready to get started?

Try AutoSPF free — no credit card required.

Book a Demo