SPF Record Generator

Pick the services that send your mail and get one SPF record, with the DNS lookups it costs receivers counted live as you build it.

RFC 7208 lookup walk, the same as our SPF checker · 71 senders' documented includes · built in your browser
Example

An example record for example.com

Type your domain above to start from what it publishes now, or change anything below. The record on the right updates as you go.

Who sends mail as example.com?
Your own servers
IPv4 addresses or ranges
IPv6 addresses or ranges
Other includes
A domain a vendor told you to include.
allMail from any other server

Unlisted servers are marked suspicious, not refused. With DMARC at quarantine or reject, DMARC decides on DKIM. M3AAWG recommends ~all.

This domain sends no mail
v=spf1 -all: no server may send as it.

What receivers spend on this record

The 10-lookup budget · example.com0 of 2 voids

/ 10 lookups used

110

DNS lookup void

Counting the includes…

Where the lookups go

include:_spf.google.comGoogle Workspace1

Before you publish

Ready to publish

One record, with nothing receivers would skip or misread.

Good

Where do I paste this?

Pick your DNS host: the fields below are written the way its form wants them.

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

After you publish

Full check: example.comThe link carries these settings, never a key. Asked from your browser: Cloudflare's resolver, Google's as a second opinion.

How do I create an SPF record?

List every service that sends mail as your domain, put their include: terms and your own servers' addresses in one TXT record at the domain, and end it with ~all.

Put the cheap terms first: IP addresses cost no DNS lookup, a and mx cost one each, includes cost one plus whatever they contain.

Then count: receivers stop at 10 DNS lookups. The SPF builder above walks every include live, so the count is what receivers will see.

Who sendsGoogle WorkspaceMailjet192.0.2.25
The record, in the order receivers read it
v=spf1ip4:192.0.2.250 lookupsinclude:_spf.google.com1 lookupinclude:spf.mailjet.com1 lookup~all0 lookups
From senders to one record
SPF record generator counting the DNS lookups of a record over the limit of 10, with the senders that cost mostSPF record generator counting the DNS lookups of a record over the limit of 10, with the senders that cost mostThe count receivers will reachEvery include walked live from your browser, nested ones too, exactly as a receiver counts.One cell per lookupColoured by the sender that spends it; past 10 the cells are hatched: a permanent error.Where the lookups goEach term with its mark, its nested includes and what it costs.Who spends mostOver 10, the biggest spenders and the honest ways back under, flattening's catch included.Senders that live elsewhereServices whose SPF goes on a subdomain, or nowhere, say where.
Microsoft 365, Freshdesk, Salesforce, Zendesk and Mimecast in one record: each include walked live from the browser, far over the limit of 10, with the senders that cost most and the ways back under.

SPF record syntax: what goes in an SPF record?

Mechanisms that name who may send (ip4, ip6, a, mx, include, exists) and one ending, all or redirect, each with a qualifier; every term that asks DNS costs one of the 10 lookups.

A qualifier says what a match means: + pass (the default), - fail, ~ softfail, ? neutral. Receivers read left to right and stop at the first match.

ptr is deprecated and slow: don't use it.

TermExampleDNS lookupsUse it for
ip4ip4:192.0.2.0/240Your own IPv4 servers
ip6ip6:2001:db8::/320Your own IPv6 servers
aa1The domain's own address
mxmx1 + up to 10 namesInbound servers that also send
includeinclude:_spf.google.com1 + its ownA service's record
existsexists:%{i}._spf.example.com1Per-address checks (macros)
redirectredirect=_spf.example.com1Use another domain's whole record
all~all0Everything else (the ending)
+pass-fail~softfail?neutral
Every mechanism and what it costs

SPF records for Google Workspace, Microsoft 365 and others

Google Workspace is include:_spf.google.com and Microsoft 365 is include:spf.protection.outlook.com; most services publish one include: term, and some need nothing in your record at all.

Each cost below was measured on the service's live record and includes everything nested inside it, which is what a receiver spends.

Services marked elsewhere send with their own return path or a subdomain of yours, so their SPF lives there.

ServiceAdd to your recordLookupsWhere
Google Workspaceinclude:_spf.google.com1your record
Microsoft 365include:spf.protection.outlook.com1your record
Zoho Mailinclude:zohomail.com2your record
Amazon SESinclude:amazonses.com1a subdomain
SendGridinclude:sendgrid.net2a subdomain
Mailguninclude:mailgun.org5a subdomain
Mailchimp——nothing to add
Brevo—1nothing to add
HubSpotinclude:<HubID>.spf0N.hubspotemail.net—your record
Salesforceinclude:_spf.salesforce.com2your record
Zendeskinclude:mail.zendesk.com1your record
Freshdeskinclude:email.freshdesk.com7your record
Postmark—1nothing to add
Mimecast (global)include:_netblocks.mimecast.com9your record
Proton Mailinclude:_spf.protonmail.ch2your record
Fastmailinclude:spf.messagingengine.com1your record
Senders, their include and what it costs

What is the SPF 10-lookup limit?

Receivers stop after 10 terms that ask DNS, nested includes counted, and SPF then fails with a permanent error for every message; a third lookup that comes back empty fails it too (RFC 7208).

Get back under by moving a sender to a subdomain with its own record, dropping a or mx if those servers don't send, or asking the vendor for a narrower include.

Flattening, replacing an include by its IP addresses, saves lookups but goes stale the day the vendor changes addresses: recheck it every month.

12 / 10 · permanent error

mx1include:spf.protection.outlook.com1include:email.freshdesk.com7include:_spf.salesforce.com2include:mail.zendesk.com1
SubdomainDrop a/mxNarrower includeFlatten (goes stale)
Five senders, 12 lookups

Should SPF end with ~all or -all?

Use ~all on a domain that sends mail and -all on one that doesn't: with DMARC at enforcement, DMARC decides on DKIM, while -all can get forwarded mail refused before DMARC runs.

M3AAWG recommends ~all for sending domains and -all for domains that send no mail. Google documents ~all for Workspace; Microsoft documents -all for Microsoft 365.

~allsoftfailAccepted, marked suspicious; DMARC decides with DKIM
-allfailMay be refused at once, even if DKIM passes
?allneutralAs if you had no SPF
A message from a server you didn't list

Which senders don't need to be in your SPF record?

Services that send with their own return path, like Mailchimp, Postmark, SparkPost, Klaviyo and Shopify, pass SPF on their own domain; Amazon SES, SendGrid and Mailgun belong on a sending subdomain of yours.

SPF checks the envelope sender (Return-Path), not the From address people see. For DMARC those services align through DKIM, so publish their DKIM records instead.

From (what people see)From: news@example.com
Return-Path (what SPF checks)Return-Path: bounce@esp.example.net

Nothing to add here

MailchimpMandrillPostmarkSparkPostBrevoKlaviyoShopifyDynamics 365

On a subdomain of yours

Amazon SESSendGridMailgun
SPF checks the Return-Path, not the From line

Can a domain have two SPF records?

No: with two v=spf1 records at one name, receivers stop with a permanent error and SPF fails, so merge them into one record.

Keep every sender from both, one ending, and count the lookups of the merged record: two records that each fit can be over 10 together.

Published at example.orgv=spf1 include:_spf.google.com ~allv=spf1 include:spf.protection.outlook.com -all
One recordv=spf1 include:_spf.google.com include:spf.protection.outlook.com ~all
Two records, merged into one

How do long SPF records work with DNS hosts?

A TXT string holds 255 bytes; longer records are split into several strings that receivers join with nothing between them, and most DNS hosts split them for you.

Cloudflare and Azure take the whole value in one field; Route 53 and Google Cloud DNS want quoted 255-byte strings. RFC 7208 asks to keep the whole answer under 450 bytes.

v=spf1 ip4:198.51.100.1 ip4:198.51.100.2 ip4:198.51.100.3 ip4:198.51.100.4 ip4:198.51.100.5 ip4:198.51.100.6 ip4:198.51.100.7 ip4:198.51.100.8 ip4:198.51.100.9 ip4:198.51.100.10 ip4:198.51.100.11 ip4:198.51.100.12 ip4:203.0.113.20 ip4:203.0.113.21 ip4:203.0.113.22 ip4:203.0.113.23 ip4:203.0.113.24 include:_spf.google.com ~all
1255 B272 B
example.com. 3600 IN TXT ( "v=spf1 ip4:198.51.100.1 ip4:198.51.100.2 ip4:198.51.100.3 ip4:198.51.100.4 ip4:198.51.100.5 ip4:198.51.100.6 ip4:198.51.100.7 ip4:198.51.100.8 ip4:198.51.100.9 ip4:198.51.100.10 ip4:198.51.100.11 ip4:198.51.100.12 ip4:203.0.113.20 ip4:203.0.113.21 ip4:203"
	".0.113.22 ip4:203.0.113.23 ip4:203.0.113.24 include:_spf.google.com ~all" )
A long record, as DNS stores it

SPF Record Generator FAQ

What is an SPF record?

An SPF record is a TXT record at your domain, starting with v=spf1, that lists the servers allowed to send mail using your domain in the envelope sender. Receivers compare the sending server with that list and pass, softfail or fail the message. It's defined in RFC 7208, and DMARC uses its result when the domains align.

What is the SPF record for Google Workspace?

v=spf1 include:_spf.google.com ~all. That single include covers Google's sending servers and costs one DNS lookup of your ten. If other services also send as your domain, add their include terms before the ending, and keep one record: a second v=spf1 record makes SPF fail for everyone.

What is the SPF record for Microsoft 365?

The SPF record for Office 365, now Microsoft 365, is v=spf1 include:spf.protection.outlook.com -all, as Microsoft documents it; ~all works too and is gentler with forwarded mail. The include costs one DNS lookup. Government clouds use their own includes, such as spf.protection.office365.us for GCC High, which the generator lists as separate senders.

Can I have two SPF records?

No. With two v=spf1 records at the same name, receivers stop with a permanent error and SPF fails for every message. Merge them: keep every sender from both in one record with one ending. Load your domain in the generator and it merges duplicates for you, then counts the lookups of the result.

What happens if my SPF record has more than 10 lookups?

Receivers stop at the eleventh DNS-querying term and return a permanent error, so SPF fails for every message, including legitimate ones. DMARC can still pass through aligned DKIM, but SPF stops helping. Move a sender to a subdomain, drop a or mx where those servers don't send, or ask a vendor for a narrower include.

Should I use ~all or -all?

Use ~all for a domain that sends mail and -all for one that doesn't. With ~all, failing mail is marked suspicious and DMARC decides using DKIM; with -all, some receivers refuse it outright, which can catch forwarded mail before DMARC runs. M3AAWG recommends ~all for sending domains.

Do subdomains need their own SPF record?

Yes, if they send mail. SPF isn't inherited: news.example.com is checked against its own TXT record, not example.com's. A subdomain that sends nothing should publish v=spf1 -all, and services like Amazon SES or Mailgun expect their record on the sending subdomain you set up with them.

Where do I add the SPF record?

At your DNS host, as a TXT record on the domain itself: type @ in the name field (Route 53 wants it empty), and paste the value. If an SPF record is already there, edit it instead of adding another. Pick your host in the generator to see its exact field names and how it takes long values.

What is SPF flattening, and should I use it?

Flattening replaces include terms with the IP addresses they contain, so the record needs fewer DNS lookups. It works, but the copy goes stale whenever a vendor changes its addresses, and mail from the new ones fails SPF. Prefer a subdomain or a narrower include; if you flatten, recheck the record every month.

Is the SPF generator free, and is anything sent to your server?

It's free, with no sign-up: this SPF record creator builds the record in your browser, and every include is counted by DNS questions your browser sends over HTTPS to Cloudflare's resolver (and Google's when Cloudflare is slow), so your domain and record don't pass through our server. Nothing you type is stored.

Missing something?Suggest a feature or a new tool