SPF Record Syntax Explained, With Examples

A complete reference to Sender Policy Framework syntax: every mechanism, qualifier and modifier, how receivers evaluate an SPF record, and copy-ready SPF record examples for common setups.

November 2, 2026
9 min read
Share:
SPF Record Syntax Explained, With Examples

Introduction

An SPF record is one line of text, and most of them are copied from a provider's setup page without anyone reading them. That works until you add a second service, hit the lookup limit, or see permerror in a DMARC report.

This is a reference to Sender Policy Framework (SPF) syntax as defined in RFC 7208: what each part of the record means, how a receiving server evaluates it, and examples for the setups you are most likely to have.

If you need the bigger picture of how SPF fits with DKIM and DMARC first, start with SPF, DKIM, and DMARC: The Complete Guide.

What an SPF Record Is

An SPF record is a DNS TXT record on your domain that lists the servers allowed to send email for it. A receiving server looks it up, compares the connecting IP address with the list, and gets a result: pass, fail, softfail and so on.

example.com.  3600  IN  TXT  "v=spf1 include:_spf.google.com ~all"

Two details people get wrong:

  • SPF is always a TXT record. The old dedicated SPF record type (type 99) was deprecated in 2014. Do not publish it.
  • SPF checks the envelope sender, the MAIL FROM address (also shown as Return-Path), not the From address in the message. If the envelope sender is empty, as in bounces, it checks the HELO name instead.

Anatomy of an SPF Record

Every SPF record has the same structure:

v=spf1 [mechanisms and modifiers] [all]

Take this record:

v=spf1 ip4:203.0.113.10 include:_spf.google.com include:spf.protection.outlook.com -all
Part Meaning
v=spf1 Version. Must be first, exactly like this
ip4:203.0.113.10 This IPv4 address may send
include:_spf.google.com Servers authorised by Google's SPF record may send
include:spf.protection.outlook.com Servers authorised by Microsoft 365's record may send
-all Everything else fails

Terms are separated by single spaces and evaluated left to right.

SPF Mechanisms

Mechanisms describe a set of hosts. If the connecting IP matches, evaluation stops and the mechanism's qualifier gives the result.

Mechanism Example Matches when DNS lookup?
ip4 ip4:203.0.113.0/24 The IP is in this IPv4 address or range No
ip6 ip6:2001:db8::/32 The IP is in this IPv6 address or range No
a a or a:mail.example.com The IP is an A/AAAA address of the domain Yes
mx mx or mx:example.com The IP is one of the domain's mail servers Yes
include include:_spf.google.com The other domain's SPF record returns pass Yes
exists exists:%{i}._spf.example.com A lookup of the name returns any A record Yes
ptr ptr:example.com Reverse DNS of the IP ends in the domain Yes
all -all Always matches No

Notes on the less obvious ones:

  • a and mx without a value use the current domain. mx on example.com authorises the servers in example.com's MX records. That is only useful if your inbound servers also send, which is rare with hosted email.
  • ip4 without a prefix means a single address (/32). ip4:203.0.113.10 and ip4:203.0.113.10/32 are the same.
  • ptr should not be used. RFC 7208 says so explicitly: it is slow, unreliable, and some receivers ignore it.
  • exists with macros is for advanced setups that compute the lookup from the sender's IP. If you have not designed one on purpose, you do not need it.

include Does Not Copy the Other Record

A common misconception is that include: pastes the other domain's record into yours. It does not. The receiver evaluates the included record on its own:

  • If it returns pass, the include matches and your record returns the include's qualifier (pass, by default)
  • If it returns fail, softfail or neutral, the include simply does not match, and evaluation continues with your next term
  • If it returns permerror or has no SPF record, your whole check ends in permerror

So the -all at the end of Google's record never fails your mail. Only your own all decides what happens to unlisted senders.

Qualifiers

Each mechanism can carry a prefix that sets the result when it matches. Without a prefix, + is assumed.

Qualifier Result Meaning
+ pass Authorised (default, almost never written)
- fail Not authorised
~ softfail Probably not authorised; accept but treat as suspicious
? neutral No statement either way

In practice you only see qualifiers on all:

  • -all: anything not listed fails
  • ~all: anything not listed softfails
  • ?all: no policy; rarely useful
  • +all: everyone on the internet may send as your domain. Never publish this.

Modifiers

Modifiers use = instead of : and change how the record is processed. Each may appear only once.

redirect= hands evaluation to another domain's SPF record when nothing in yours matched. It lets many domains share one policy:

example.org.  TXT  "v=spf1 redirect=_spf.example.com"

redirect is ignored if the record contains an all mechanism, so do not combine them.

exp= points to a TXT record with an explanation string returned on fail. Few receivers show it; you can ignore it.

How a Receiver Evaluates SPF

  1. Take the domain of the envelope sender (MAIL FROM), or the HELO name if it is empty.
  2. Look up the TXT records for that domain and keep the one starting with v=spf1. If there is none, the result is none. If there are two, it is permerror.
  3. Evaluate the terms left to right. The first mechanism that matches gives the result.
  4. If nothing matches and there is a redirect, evaluate the target record.
  5. If nothing matches and there is no redirect, the result is neutral.

Throughout the process, the receiver counts DNS lookups. More than 10 lookup-causing terms (include, a, mx, ptr, exists, redirect), counting nested ones, gives permerror. More than 2 void lookups (names that return nothing) also gives permerror.

If your record is near that limit, SPF Record: Too Many DNS Lookups explains how to bring it down.

SPF Record Examples

Replace example.com with your domain. Use only the includes for services that actually send email as your domain.

Google Workspace only:

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

Microsoft 365 only:

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

Microsoft 365 plus your own server:

v=spf1 ip4:203.0.113.10 include:spf.protection.outlook.com ~all

Google Workspace plus a marketing platform:

v=spf1 include:_spf.google.com include:spf.brevo.com ~all

A domain that never sends email:

v=spf1 -all

This is the right record for parked domains and for domains used only for a website. It tells receivers that any mail claiming to come from the domain is forged.

Several domains sharing one policy:

_spf.example.com.  TXT  "v=spf1 include:_spf.google.com ip4:203.0.113.10 ~all"
example.com.       TXT  "v=spf1 redirect=_spf.example.com"
example.org.       TXT  "v=spf1 redirect=_spf.example.com"

A sending subdomain with its own record (for example, Amazon SES with a custom MAIL FROM):

mail.example.com.  TXT  "v=spf1 include:amazonses.com ~all"

Subdomains do not inherit SPF from the parent domain. Each name used as an envelope sender needs its own record.

Records Longer Than 255 Characters

A single string in a TXT record cannot exceed 255 characters. Longer SPF records are split into several quoted strings, which receivers join with no space between them:

example.com.  TXT  "v=spf1 ip4:203.0.113.10 ip4:203.0.113.11 include:_spf.google.com " "include:spf.protection.outlook.com ~all"

Note the trailing space inside the first string. Without it, the joined record reads ..._spf.google.cominclude:... and breaks. Most DNS panels split long values for you; check the result with a lookup.

Keep the whole response small too: a long SPF record is usually a sign it needs fewer includes, not more strings.

Common Syntax Errors

Error Example Fix
Two SPF records Two TXT records with v=spf1 Merge into one (how)
Typo in the version v=spf, v=SPF1 with a stray character Exactly v=spf1
Space after the colon include: _spf.google.com include:_spf.google.com
Missing all v=spf1 include:_spf.google.com End with ~all or -all
Terms after all v=spf1 -all include:... all goes last; anything after it is ignored
+all v=spf1 +all Never authorise everyone
Smart quotes from a document “v=spf1 ...” Plain text, straight quotes or none
Record on the wrong name www.example.com instead of example.com Publish on the envelope sender domain

SPF and DMARC Alignment

A pass is not the end of the story. DMARC only counts an SPF pass if the envelope sender domain aligns with the From domain. When a marketing platform sends with its own bounce domain (bounces.esp-provider.net), SPF passes for that domain, but not for yours.

That is why many providers ask you to set up a custom return-path or bounce domain under your own domain, and why DKIM signed with your domain is often the more reliable path to DMARC. DMARC Alignment Failed covers both cases.

Checklist

  • Exactly one TXT record starts with v=spf1
  • Every include belongs to a service that sends as your domain
  • No ptr, no +all
  • The record ends with ~all or -all
  • 10 DNS lookups or fewer, nested includes counted
  • Non-sending domains publish v=spf1 -all

Next Steps

  1. Check your record and count lookups: SPF Checker →
  2. Build a valid record from your providers: SPF Record Generator →
  3. Find the right include for each service: Email Services Directory →
  4. See which senders pass in practice: Start free → — DMARC aggregate reports show SPF results per sending source, so you spot a missing include before a policy blocks the mail.

Related Articles:

Tags:spfdnsemail-authentication

Ready to improve your email deliverability?

Start monitoring your DMARC reports and get insights into your email authentication setup.

Start Free Trial