SPF (Sender Policy Framework) is the first line of defense in email authentication. It lets you declare in your DNS which servers are allowed to send email for your domain. Simple on the surface, it hides subtleties that trip up even experienced admins.

What Does SPF Actually Do?

When a receiving server gets an email from contact@yourdomain.com, it asks one question: “Is this server allowed to send for this domain?”

To answer, it checks the SPF record for yourdomain.com in DNS. That record lists the authorized IPs and servers.

Without SPF: any server can claim to send on your behalf. It’s an open door for spoofing.

With SPF: only servers you’ve explicitly authorized pass verification.

Anatomy of an SPF Record

An SPF record is a DNS TXT record placed at your domain’s root:

v=spf1 include:_spf.google.com include:spf.sendinblue.com ip4:203.0.113.50 -all

Let’s break it down:

ElementPurpose
v=spf1Protocol version (required, always first)
include:Authorizes servers declared in another domain’s SPF
ip4: / ip6:Authorizes a specific IP or CIDR block
aAuthorizes the IP of your domain’s A record
mxAuthorizes your MX server IPs
redirect=Redirects to another domain’s SPF (replaces everything)
-allReject anything that doesn’t match (fail)
~allMark as suspicious (softfail)
?allNeutral, no opinion

Qualifiers

Each mechanism can be prefixed with a qualifier:

  • + (pass, default), authorized
  • - (fail), rejected
  • ~ (softfail), suspicious, accepted but flagged
  • ? (neutral), no indication

Best practice: always use -all in production. ~all is an acceptable compromise during rollout.

The 10 DNS Lookup Limit

This is the most common trap. RFC 7208 imposes a strict limit: an SPF record cannot trigger more than 10 DNS lookups.

Each include:, a, mx, redirect and exists counts as one lookup. ip4: and ip6: don’t count (they’re static values).

Example That Exceeds the Limit

v=spf1 include:_spf.google.com include:spf.protection.outlook.com include:spf.sendinblue.com include:servers.mcsv.net include:_spf.salesforce.com include:mail.zendesk.com include:spf.freshdesk.com -all

This looks correct, but each include: can itself contain nested include: directives. Google alone triggers 3-4 lookups. You easily exceed 10.

Result: permerror, the SPF is invalid, emails fail verification.

Solutions

  1. Replace include: with ip4:/ip6: for services with stable IPs
  2. Use a “flattening” service that resolves includes to IPs at regular intervals
  3. Dedicate a subdomain per service (marketing.yourdomain.com for Mailchimp, etc.)

Check your SPF’s lookup count with our free SPF Checker, it shows every resolution in detail.

Step-by-Step Setup

1. Inventory Your Sending Sources

List every service that sends email for your domain:

  • Your mail server (Exchange, Postfix, etc.)
  • Marketing services (Mailchimp, Brevo, HubSpot…)
  • Transactional services (SendGrid, SES, Postmark…)
  • CRM (Salesforce, Pipedrive…)
  • Support (Zendesk, Freshdesk…)

A free Sender Audit scan automatically shows all detected sources.

2. Build Your Record

For each service, find the SPF mechanism to add (usually in their docs). Assemble:

v=spf1 include:_spf.google.com include:spf.sendinblue.com ip4:203.0.113.50 -all

Free tool: our SPF Generator helps you build your record and automatically checks the 10 lookup limit.

3. Publish to DNS

Add a TXT record at your domain root (@). Important: there must be only one SPF record per domain. If one already exists, modify it rather than adding a second.

4. Test

Use the SPF Checker to validate:

  • Syntax is correct
  • Lookup count is ≤ 10
  • All your services are included
  • The final qualifier is -all

SPF and DMARC: The Connection

SPF alone isn’t enough. For SPF to contribute to DMARC, the Return-Path domain (envelope) must align with the From: domain (visible header).

Many third-party services use their own domain as Return-Path, SPF passes but DMARC fails on SPF alignment. That’s why DKIM is essential as a complement.

To understand how everything fits together, read our DMARC guide.

Common Mistakes

  1. Multiple SPF records on the same domain → invalid
  2. Exceeding 10 lookupspermerror
  3. Using +all → authorizes everyone (worse than no SPF)
  4. Forgetting a service → its emails fail SPF
  5. Not maintaining the record → discontinued services waste lookup slots

Go Further


Questions? Join the community on Matrix.