SPF Record Syntax Basics: The Grammar of Email Authentication
SPF records look like cryptic code at first glance, but they follow a clear, logical grammar. Once you understand the syntax rules, you can read, write, and debug SPF records with confidence.
The Basic Structure
v=spf1 [mechanism1] [mechanism2] ... [mechanismN] [modifier]
v=spf1(Required): Version identifier. Must be the first element. Tells receiving servers this is an SPF record using version 1.- Mechanisms (Ordered): Define which servers are authorized. Evaluated from left to right. The first matching mechanism determines the result.
- Modifiers (Optional): Provide additional instructions like redirects or error messages. Appear after all mechanisms.
Evaluation Rules
- Receiving server evaluates mechanisms in order (left to right).
- When a mechanism matches the sender's IP address, evaluation stops immediately.
- The qualifier of the matching mechanism determines the result (Pass, Fail, SoftFail, Neutral).
- If no mechanism matches, the default result is Neutral (
?allequivalent), but most records end with an explicitallmechanism.
all mechanism.
Every SPF Mechanism Explained: Detailed Reference
Each mechanism serves a specific purpose. Understanding when and how to use each one is key to building efficient SPF records.
1. include: The Most Common Mechanism
Syntax: include:domain.com
What it does: Includes the SPF record from another domain. The receiving server fetches that domain's SPF record and evaluates it as if it were part of the current record.
When to use: For email service providers (Google Workspace, Microsoft 365, SendGrid, etc.). Instead of manually maintaining their IP ranges, you include their SPF record.
Important behavior: If the included record returns a match (Pass, Fail, SoftFail, or Neutral), evaluation stops and that result is returned. If the included record returns None (no SPF) or PermError, include: returns Neutral and evaluation continues to the next mechanism.
Example: include:_spf.google.com - Authorizes all IPs in Google Workspace's SPF record.
2. ip4: Direct IPv4 Authorization
Syntax: ip4:ipv4-address or ip4:ipv4-address/cidr
What it does: Authorizes a specific IPv4 address or CIDR range. No DNS lookup required (0 lookups).
When to use: For your own mail servers, web servers sending email, or any server with a static public IP.
Examples:
ip4:192.168.1.100- Single IP addressip4:192.168.0.0/16- Entire Class B subnet (65,536 addresses)ip4:203.0.113.0/24- Class C subnet (256 addresses)
3. ip6: IPv6 Authorization
Syntax: ip6:ipv6-address or ip6:ipv6-address/cidr
What it does: Authorizes a specific IPv6 address or CIDR range. No DNS lookup required (0 lookups).
When to use: For mail servers using IPv6. As IPv6 adoption grows, this becomes increasingly important.
Examples:
ip6:2001:db8::1- Single IPv6 addressip6:2001:db8::/32- IPv6 CIDR range
4. a: Domain's A Record Authorization
Syntax: a or a:domain.com
What it does: Authorizes the IP address(es) from the domain's A record(s). Consumes 1 DNS lookup.
When to use: When your mail server's IP is the same as your web server's IP, or when you want to authorize based on a domain's A record.
Example: a:mail.yourdomain.com - Authorizes whatever IP address mail.yourdomain.com resolves to.
5. mx: Domain's MX Record Authorization
Syntax: mx or mx:domain.com
What it does: Authorizes the IP addresses of all MX records for the domain. Consumes 1 lookup per MX record.
When to use: When your incoming and outgoing email use the same servers (common for self-hosted mail).
Example: mx - Authorizes IPs of your domain's own MX records.
6. exists: Conditional Authorization (Advanced)
Syntax: exists:domain.com
What it does: Performs a DNS lookup for the specified domain. If the lookup returns ANY result (even an empty A record), the mechanism matches. Consumes 1 DNS lookup.
When to use: Complex, dynamic authorization scenarios. Most domains never need this.
Example: exists:%{i}._spf.yourdomain.com - Uses a macro to check if a hostname matching the sender's IP exists.
7. ptr: (Deprecated - Avoid Using)
Syntax: ptr or ptr:domain.com
What it does: Performs a reverse DNS lookup to check if the sender's IP's PTR record matches the domain.
Warning: This mechanism is deprecated in RFC 7208 (the current SPF standard) because it's slow, unreliable, and consumes many DNS lookups. Do not use ptr in new SPF records.
SPF Modifiers: redirect and exp
Modifiers appear after all mechanisms and provide additional instructions. Unlike mechanisms, modifiers don't evaluate against the sender's IPβthey change overall record behavior.
redirect=domain.com
Syntax: redirect=domain.com
What it does: Abandons evaluation of the current SPF record and instead evaluates the SPF record of the specified domain. The results (Pass, Fail, SoftFail, etc.) are returned as if they came from the original domain.
When to use: When you want to delegate SPF authority to another domain. For example, if multiple domains use the same email infrastructure, you can have one master SPF record and redirect all other domains to it.
Important: A record cannot have both mechanisms AND a redirect modifier. If you use redirect=, it must be the only element after v=spf1. (You can have mechanisms before the redirect? The RFC is ambiguous; best practice is to avoid mixing.)
Example: v=spf1 redirect=master-spf.yourdomain.com
exp=domain.com (Explanation String)
Syntax: exp=domain.com
What it does: Specifies a domain with a TXT record containing an explanation message. When an email fails SPF, the receiving server may query this TXT record and display the explanation to the sender in bounce messages.
When to use: To provide friendly error messages when legitimate senders have misconfigured email clients. Rarely used in practice.
Example:
# SPF record
v=spf1 include:_spf.google.com -all exp=explain._spf.yourdomain.com
# TXT record at explain._spf.yourdomain.com
"You are not authorized to send email for yourdomain.com. Please use yourdomain.com's SMTP server (smtp.yourdomain.com) to send."
Qualifiers: How to Handle When a Mechanism Matches
Every mechanism can be prefixed with a qualifier that tells the receiving server what to do when that mechanism matches the sender's IP.
The Four Qualifiers
+(Pass - Default): The sender is authorized. If no qualifier is written,+is assumed.+include:domain.comis the same asinclude:domain.com.-(Fail): The sender is explicitly NOT authorized. The email should be rejected or sent to spam.~(SoftFail): The sender likely isn't authorized, but accept the email anyway (mark as suspicious).?(Neutral): No statement about authorization. The result is treated as "no SPF." Avoid this.
Using Qualifiers Strategically
Qualifiers allow granular control. For example:
v=spf1 +ip4:192.168.1.100 -ip4:192.168.1.200 ~all
In this record:
192.168.1.100is explicitly authorized (Pass).192.168.1.200is explicitly blocked (Fail), even though it comes before the~allcatch-all.- All other IPs get SoftFail.
- (Fail) before the final all mechanism. Using it incorrectly can block legitimate senders. Only use explicit Fail mechanisms when you are absolutely certain an IP or range should never send email for your domain.
Real-World SPF Record Examples and Use Cases
Here are common SPF configurations for different scenarios. Use these as templates for your own records.
Example 1: Google Workspace Only (Small Business)
v=spf1 include:_spf.google.com ~all
Example 2: Microsoft 365 Only
v=spf1 include:spf.protection.outlook.com ~all
Example 3: Google Workspace + SendGrid + Own Server
v=spf1 include:_spf.google.com include:sendgrid.net ip4:203.0.113.50/32 ~all
Example 4: Self-Hosted Mail Server Only
v=spf1 ip4:203.0.113.50/32 mx ~all
Example 5: Complex Enterprise (Multiple Services)
v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:servers.mcsv.net include:sendgrid.net ip4:203.0.113.0/24 ip6:2001:db8::/32 ~all
Example 6: No Email (Null SPF)
v=spf1 -all
Use for domains that should NEVER send email. Explicit Hard Fail tells receiving servers to reject all email.
Example 7: Redirect to Master SPF
v=spf1 redirect=_spf.yourdomain.com
Testing and Validation Tools for SPF Syntax
Always test your SPF record before publishing. A syntax error can cause PermError and break email delivery.
Our SPF Checker (Recommended)
Our tool validates SPF syntax, counts DNS lookups, resolves all includes, and provides detailed error messages.
Command-Line Testing
# Check if SPF record exists
dig yourdomain.com TXT +short
# Test SPF evaluation for a specific IP
spfquery --ip 192.168.1.100 --sender sender@yourdomain.com --helo helo.yourdomain.com
v=spf1), followed by mechanisms (evaluated left to right), ending with a modifier (optional). Use include: for email providers, ip4:/ip6: for your own servers, and always end with ~all or -all. Test your record with our SPF Checker before publishing to avoid syntax errors and PermError failures.
