BookMySpot

Deliverability

SPF Record Explained: Syntax, Examples, and Common Mistakes

An SPF record is a DNS TXT record that lists which servers may send email using your domain in the envelope sender (the “MAIL FROM” or Return-Path address). Receiving servers look it up, compare the connecting IP address against the list, and return a result such as pass, fail, or softfail. A typical record looks like v=spf1 include:_spf.google.com ~all, and each domain may publish only one.

This guide covers the syntax piece by piece, shows records for common setups, and walks through the mistakes that break SPF in practice.

What an SPF record does (and what it doesn’t)

SPF is defined in RFC 7208. It lets a domain owner authorize hosts to use the domain in two SMTP identities: the HELO/EHLO name and the MAIL FROM address. That second one is the address bounces go to, not the From address your recipient sees.

That distinction matters more than anything else in this article:

  • SPF checks the envelope sender (also called Return-Path, bounce address, or 5321.MailFrom).
  • SPF does not check the visible From: header (5322.From).
  • Linking the two is DMARC’s job, through a concept called alignment. See DMARC alignment: strict vs relaxed.

So an SPF pass alone does not prove the message came from the brand in the From line. It proves the bounce domain authorized the sending IP. That’s still useful, and mailbox providers require it. Google’s sender guidelines say all senders must set up SPF or DKIM, and anyone sending more than 5,000 messages a day to Gmail must set up both.

SPF record syntax, piece by piece

Every SPF record has three parts: a version tag, a list of mechanisms, and usually a final all.

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

Receivers evaluate the terms left to right and stop at the first match.

The version tag

The record must start with exactly v=spf1. RFC 7208 says records that don’t begin with this tag are discarded, so v=spf2, v=SPF1 with odd spacing from a broken editor, or a leading quote character in the wrong place can make the whole record invisible.

Mechanisms

MechanismWhat it matchesCosts a DNS lookup?
ip4:203.0.113.10 or ip4:203.0.113.0/24A single IPv4 address or CIDR rangeNo
ip6:2001:db8::/32IPv6 address or rangeNo
a / a:mail.example.comThe A/AAAA records of the domainYes
mx / mx:example.comThe IPs of the domain’s MX hostsYes
include:_spf.example.netWhatever the other domain’s SPF record authorizesYes
exists:%{i}._spf.example.comMatches if an A record exists for the built nameYes
ptrReverse DNS of the senderYes, and deprecated
allEverythingNo

The lookup column matters because RFC 7208 (section 4.6.4) caps the DNS-querying terms at 10 per evaluation. Go over and the result is a permanent error. We cover that in detail in SPF “too many DNS lookups”: how to fix it.

The ptr mechanism is officially “do not use.” RFC 7208 section 5.5 says it should not be published because it is slow and unreliable. If you see it in an old record, remove it.

Qualifiers

Each mechanism can carry a prefix that decides the result when it matches:

QualifierResultTypical use
+ (default)passAuthorized senders; you almost never type it
-fail-all at the end: everything else is unauthorized
~softfail~all: everything else is probably unauthorized
?neutral?all: no opinion; testing only

The all mechanism

all matches every IP, so it goes last as the default. Per RFC 7208 section 5.1, anything listed after all is ignored. If there is no all and no redirect, the default result is neutral, which tells receivers nothing.

Modifiers: redirect and exp

  • redirect=_spf.example.com hands the whole evaluation to another domain’s record. Useful when many domains share one policy. It counts as a DNS lookup and is ignored if the record also contains all.
  • exp= points to an explanation string for rejections. Few senders use it.

SPF record examples for common setups

Use these as patterns, then check your provider’s documentation for the exact include value.

Google Workspace only. Google’s SPF setup page gives:

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

Microsoft 365 only. Microsoft’s SPF configuration guide gives:

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

Your own server plus Microsoft 365. Add the server’s public IP:

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

A sending subdomain for Amazon SES. If you set a custom MAIL FROM domain such as bounce.example.com, AWS’s MAIL FROM documentation has you publish this on that subdomain, along with an MX record pointing to the regional feedback endpoint:

bounce.example.com.  TXT  "v=spf1 include:amazonses.com ~all"
bounce.example.com.  MX   10 feedback-smtp.us-east-1.amazonses.com

A domain that never sends mail. Parked and defensive domains should say so:

v=spf1 -all

Microsoft’s guide uses this exact record for parked domains. Pair it with a DMARC p=reject record and a null MX (MX 0 .) for full coverage. See what is an MX record for the null MX format.

-all or ~all: which should you use?

This is the most common SPF question, and the two big mailbox providers publish different defaults:

  • Google recommends ~all for Workspace domains on its SPF setup page.
  • Microsoft recommends -all for Microsoft 365 domains. Its reasoning: DMARC treats both -all and ~all as SPF failures, and -all lets DMARC act on messages that also lack a DKIM signature.

In practice, once you have DMARC deployed, the difference shrinks, because DMARC policy decides what happens to failing mail. A reasonable rule:

  1. Start with ~all while you inventory every service that sends as your domain.
  2. Watch your DMARC aggregate reports for legitimate sources failing SPF. Our guide on reading DMARC aggregate reports shows how.
  3. Move to -all once the reports are clean, if your DMARC rollout calls for it.

Avoid +all. It authorizes the entire internet to send as you.

Common SPF record mistakes

Publishing two SPF records

RFC 7208 is explicit: a domain must not have multiple SPF records, and if a receiver finds more than one, the result is permerror. This usually happens when a second vendor’s setup wizard tells you to “add a TXT record” and you add a new one instead of editing the existing one. Merge them:

Wrong (two records):
v=spf1 include:_spf.google.com ~all
v=spf1 include:sendgrid.net ~all

Right (one record):
v=spf1 include:_spf.google.com include:sendgrid.net ~all

Exceeding 10 DNS lookups

Every include, a, mx, exists, and redirect counts, and nested includes count too. Microsoft’s guide notes that fewer than 10 include statements doesn’t guarantee fewer than 10 lookups, because each include can contain more includes. Count recursively, or use the SPF checker on this site.

Syntax typos

Microsoft’s troubleshooting table lists three classics, and we see them constantly:

  • A trailing dot: include:spf.protection.outlook.com.
  • An equals sign instead of a colon: include=spf.protection.outlook.com
  • A space after the colon: include: spf.protection.outlook.com

RFC 7208 section 4.6 says any syntax error causes an immediate permerror for the whole record, not just the broken term.

Too many void lookups

A “void lookup” is a DNS query that returns no records or NXDOMAIN, often from an include pointing to a vendor you stopped using. RFC 7208 says implementations should limit void lookups to two, and exceeding that is also a permerror. Remove includes for services you’ve cancelled.

Forgetting subdomains

Each hostname that appears in a MAIL FROM address needs its own SPF record. Microsoft’s documentation points out that the record on example.com does not cover marketing.example.com. SPF has no inheritance.

Records that are too long

A single TXT string is limited to 255 characters. RFC 7208 section 3.3 says a long record can be split into multiple strings, which receivers concatenate without adding spaces. So put the space inside the string:

"v=spf1 ip4:203.0.113.0/24 include:_spf.google.com " "include:amazonses.com -all"

Section 3.4 also recommends keeping the whole DNS response under 512 octets so it fits in a single UDP packet.

Using the ptr mechanism

Covered above: deprecated, slow, and some receivers effectively ignore it. Replace it with ip4/ip6 or the right include.

How to check your SPF record

From a terminal:

dig +short TXT example.com | grep spf1

On Windows PowerShell:

Resolve-DnsName -Type TXT example.com | Where-Object { $_.Strings -match "spf1" }

Then test the real thing. Send a message to a Gmail account, open it, choose “Show original,” and look for spf=pass in the Authentication-Results header. If you see spf=permerror, go back through the mistakes list above.

Gmail’s SMTP error reference shows what failures look like on the wire: 4.7.27 means mail was rate limited because SPF didn’t pass, and 5.7.27 means it was blocked for the same reason.

SPF is one third of authentication

SPF on its own breaks easily. Forwarding changes the connecting IP, so forwarded mail often fails SPF even when the original was fine (the existing post on ARC and forwarded mail covers why). DKIM survives forwarding better, and DMARC ties both to the visible From domain. If you’re setting things up from scratch, follow how to set up SPF, DKIM, and DMARC step by step.

One more practical note: authentication protects your domain, but it does nothing for the addresses you send to. If your list has typos and dead domains, you’ll still bounce. Run new addresses through our free email verifier to catch bad syntax, domains with no MX records, disposable domains, and common typos like gmial.com before they hit your sender reputation. It doesn’t log into mailboxes, but it removes the obvious failures for free.

FAQ

Can I have two SPF records on one domain?

No. RFC 7208 says a domain must not publish more than one SPF record, and receivers return permerror if they find two. Combine all your mechanisms into a single record that starts with v=spf1.

Should I use the SPF record type or TXT?

Use TXT. A dedicated SPF record type existed in the original experimental spec, but RFC 7208 discontinued it and says SPF records must be published as TXT. Some DNS dashboards still show an “SPF” option; ignore it.

Does SPF check the From address my recipients see?

No. SPF checks the envelope sender (Return-Path) and optionally the HELO name. The visible From address is tied to SPF only through DMARC alignment, which requires the two domains to match.

How long does an SPF change take to work?

It depends on the TTL of the old record. Microsoft recommends a TTL of at least 3,600 seconds (one hour) for SPF records, so expect changes to propagate within that window once caches expire. Test with a fresh message rather than an old one.

Do I need SPF if I already have DKIM?

Yes, if you send in volume. Google and Yahoo require both SPF and DKIM for bulk senders, and SPF also gives receivers a fast check before they process the message body.

Check your list before you send

Free email verifier: syntax, MX, disposable and role-based addresses, typos. Paste up to 100 at once.

Verify emails free