Skip to content
iBlockSpam
SPF, DKIM & DMARC

SPF record syntax and examples

By iBlockSpam Team How we check our guides Updated 9 min read 6 sources
Short answer

An SPF record is one TXT record that starts with v=spf1, lists who may send mail for your domain using mechanisms such as include, ip4 and mx, and ends with an all mechanism. For Microsoft 365 only: v=spf1 include:spf.protection.outlook.com -all. For a domain that sends no mail: v=spf1 -all.

SPF is a single DNS TXT record that lists the servers allowed to send mail using your domain. The syntax is short, but small mistakes break it completely. This guide explains each part of the record, gives working examples for common setups, and lists the mistakes we see most often. New to SPF? Start with what SPF is and how it works.

What does an SPF record look like?

Here is a typical record:

example.com.  3600  IN  TXT  "v=spf1 ip4:203.0.113.10 include:spf.protection.outlook.com -all"

Read it left to right:

  • v=spf1 marks this TXT record as SPF. It must come first.
  • ip4:203.0.113.10 allows one server by IP address.
  • include:spf.protection.outlook.com allows every server in Microsoft 365's SPF record.
  • -all says everything else fails.

Receivers check the IP address of the server that connected to them against this list, in order, and stop at the first match (RFC 7208). SPF checks the envelope sender (the MAIL FROM address, often shown as Return-Path), not the From address people see. Linking the two is DMARC's job.

What does each SPF mechanism do?

Mechanisms are the terms that match a sending IP. They're defined in section 5 of RFC 7208.

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
include include:_spf.google.com The other domain's SPF record passes for this IP Yes
a a or a:web.example.com The IP is one of that host's A/AAAA addresses Yes
mx mx The IP belongs to one of the domain's MX hosts Yes
exists exists:%{i}.rbl.example.net A lookup of the built name returns any A record Yes
ptr ptr Reverse DNS matches the domain. Don't use it Yes
all -all Always matches. Goes last No

Every mechanism marked "Yes" counts toward the limit of 10 DNS lookups per check, including lookups inside the records you include. Go over and the result is PermError. Our guide to SPF PermError: too many DNS lookups covers this in detail.

Anything after all is ignored, so all must be the last mechanism.

What do the SPF qualifiers + - ~ ? mean?

Each mechanism can have a qualifier in front. It sets the result when that mechanism matches.

Qualifier Name Result Typical use
+ Pass Authorized The default; you rarely write it
- Fail Not authorized -all at the end of a complete record
~ Softfail Probably not authorized ~all while you're still finding senders
? Neutral No statement Testing only

Because + is the default, include:x means +include:x. Never write +all; it authorizes every server on the internet.

If no mechanism matches and there's no all or redirect, the result is neutral, as if the record ended in ?all. RFC 7208 recommends always ending with an explicit all or a redirect.

What do the redirect and exp modifiers do?

Modifiers use = rather than :.

  • redirect=domain hands the whole check to another domain's SPF record when nothing else matches. It's useful when many domains share one policy, for example v=spf1 redirect=_spf.example.com. It's ignored if the record contains all, and if the target has no SPF record the result is PermError (RFC 7208, section 6.1).
  • exp=domain points to a TXT record with an explanation string for failed messages. Few receivers show it; most domains don't need it.

redirect and exp may each appear only once; a duplicate is a PermError (RFC 7208, section 6).

Which SPF record fits your setup?

Looking for one provider's exact value? See SPF records by email provider for the include each service documents and what it costs in lookups.

Microsoft 365 only

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

This is the record Microsoft gives for domains where Microsoft 365 is the only sender. Our Microsoft 365 SPF record page shows the include's measured lookup cost, and the Microsoft 365 platform page covers filtering.

Google Workspace only

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

This is the record from Google's SPF setup guide, which recommends ~all. Changing it to -all is valid once you're sure Google is your only sender. Our Google Workspace SPF record page has the details, and the Google Workspace platform page covers filtering.

Several senders on the main domain

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

Microsoft 365 for staff, an on-premises server or website at one IP, and one third-party service. Each new service adds an include to the same record. Never create a second record.

Bulk mail on a subdomain

example.com.       TXT  "v=spf1 include:spf.protection.outlook.com -all"
news.example.com.  TXT  "v=spf1 include:mailer.example.net -all"

Microsoft recommends putting services you don't directly control, such as newsletter tools, on a subdomain. The subdomain needs its own record, and it gets its own 10-lookup budget.

Parked or non-sending domain

v=spf1 -all

Microsoft gives this exact record for parked domains: no server is authorized. Pair it with a DMARC record such as v=DMARC1; p=reject; so the visible From address is protected too (RFC 9989). Do the same for any defined subdomain that never sends mail.

Domain with an inbound filtering service

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

If a filtering service only receives your mail, nothing changes in SPF. Microsoft's own guidance for an MX that points to third-party filtering uses the standard Microsoft 365 record and says to add the filter only if outbound mail goes through it.

What are the most common SPF mistakes?

Mistake What happens Fix
Two TXT records starting with v=spf1 PermError for every message (RFC 7208, section 4.5) Merge into one record
More than 10 DNS-querying terms PermError Remove unused senders, use subdomains
include=domain instead of include:domain Syntax error Use a colon
Space after the colon Syntax error include:spf.protection.outlook.com
Trailing dot after a domain RFC 7208 says it shouldn't be published (receivers must still accept it); Microsoft lists it as a common mistake include:spf.protection.outlook.com
Using ptr Slow, unreliable; RFC 7208 says it shouldn't be published Use ip4, ip6 or include
+all Authorizes everyone Use -all or ~all
?all in production SPF says nothing useful Use ~all or -all
Mechanisms after all Ignored Put all last
include of a domain with no SPF record PermError Remove it or fix the target
Using the obsolete SPF record type Ignored; SPF must be published as TXT Publish TXT only
Adding inbound-only services Wastes lookups Only list services that send

Microsoft's troubleshooting guide lists the colon, space and trailing-dot errors as common syntax mistakes.

This isn't rare. In our October 2026 scan of the Tranco top 1,000 domains, 4 domains published more than one SPF record and 22 went over the 10-lookup limit.

~all vs -all: which should you use?

Both stop SPF from vouching for unknown servers. The difference is how strongly.

  • -all (fail) says unlisted servers aren't authorized. Microsoft recommends it for Microsoft 365 domains with DKIM and DMARC, because DMARC then decides what happens to failures, and DMARC reports let you check the results.
  • ~all (softfail) says they probably aren't. Google's guide recommends it.

Under DMARC, both count as an SPF fail. In practice, the deciding factor is your DMARC policy, not the qualifier. Of the 764 top-1,000 domains in our scan that publish SPF, 438 end in -all, 274 in ~all, 19 in ?all, and 33 use redirect.

Long records and multiple strings

A single TXT string is limited to 255 characters. Longer records can be split into several quoted strings in one TXT record, which receivers join with no added space:

"v=spf1 include:spf.protection.outlook.com include:mailer.example.net "
"include:crm.example.org -all"

Note the space at the end of the first string. RFC 7208 also recommends keeping the whole record small enough to fit in a 512-byte DNS response.

How do you write or change your SPF record?

  1. List every service that sends as your domain: your mailbox platform, website forms, CRM, helpdesk, invoicing and newsletter tools. Google's sender guidelines say missing senders are more likely to be marked as spam.
  2. Get each vendor's documented include or IP range. Don't guess.
  3. Move bulk senders to a subdomain where you can.
  4. Build one record, starting with v=spf1 and ending with ~all or -all.
  5. Check it with the SPF Checker for syntax and lookup count.
  6. Replace the old record at your DNS host. Edit it; don't add a second one.
  7. Test by sending from each service to an outside mailbox and checking spf=pass in the headers.
  8. Add DKIM and DMARC. Google requires SPF or DKIM from all senders, and SPF, DKIM and DMARC from bulk senders.

Next steps

  • Run your domain through the SPF Checker to see your current record, lookup count and any syntax problems.
  • Building a record from scratch? The SPF Record Generator assembles one from your mail services and estimates its lookups. For the exact include each service documents, see SPF records by email provider.
  • Publish v=spf1 -all plus a reject DMARC policy on every domain you own that doesn't send mail.
  • Check your DMARC record with the DMARC Checker; our DMARC record examples show what to publish.
  • If you want to know when someone changes your SPF record, iBlockSpam domain monitoring sends drift alerts.

Browse our other SPF, DKIM and DMARC guides.

Frequently asked questions

Should I use ~all or -all?

Both are valid. Microsoft recommends -all for Microsoft 365 domains that also use DKIM and DMARC. Google recommends ~all in its setup guide. Once your record lists every real sender and DMARC is in place, -all is the clearer statement. If you're still discovering senders, ~all is the gentler starting point.

Can I have two SPF records?

No. RFC 7208 says a domain must not publish more than one SPF record, and receivers return PermError if they find two. Merge all your senders into one record that starts with v=spf1. Other TXT records, such as domain verification codes, can stay alongside it.

Does an SPF record cover my subdomains?

No. SPF is checked for the exact domain in the envelope sender, so news.example.com needs its own record. That's useful: each subdomain gets its own 10-lookup budget. DMARC, by contrast, can apply a parent domain's policy to subdomains.

What should an SPF record look like for a domain that doesn't send email?

Publish v=spf1 -all. It says no server is allowed to send mail using that domain. Add a DMARC record with p=reject as well, because SPF only covers the envelope sender, not the From address people see.

Do I need to add my spam filter to SPF?

Only if it sends mail for you. An inbound-only filtering service receives your mail and doesn't need to be in SPF. If you use the same provider as an outbound relay, add the include or IP addresses it documents for outbound mail.

Sources

  1. RFC 7208: Sender Policy Framework (SPF)
  2. RFC 7208, section 5: Mechanism definitions
  3. Microsoft Learn: Set up SPF to identify valid email sources for your Microsoft 365 domain
  4. Google Workspace Admin Help: Set up SPF
  5. Gmail Help: Email sender guidelines
  6. RFC 9989: DMARC

See how your domain measures up

Run a free Email Health Check: MX, SPF, DKIM, DMARC and transport security in one scan, with the raw records shown. No sign-up.

Keep reading