SPF Checker
Enter a domain to check the SPF record the way receiving servers read it: every include followed, DNS lookups counted against the limit of 10, and what happens to mail from servers the record does not list.
Result
Checking google.com…
Looking up the SPF record and following its includes…
What this SPF checker looks at
SPF (Sender Policy Framework, RFC 7208) is one TXT record at your domain that lists the servers allowed to send mail for it. A receiving server checks it against the domain of the envelope sender, the address bounces go to (shown as Return-Path in the headers), and against the server's HELO name. It does not look at the From address people see; that link is made by DMARC.
A plain SPF lookup shows you the record, but most problems hide in what the record points to. This SPF record check does what a receiver does and reports:
- The record: exactly one TXT record starting with
v=spf1at the domain, and valid syntax in every term of it and of every record it includes. - The 10-lookup limit:
include,a,mx,ptr,existsandredirecteach cost a DNS lookup, the ones inside every include too. With more than 10, receivers stop with a permanent error (RFC 7208 §4.6.4). We count through the whole tree and show what each term of your record costs. - Void lookups: terms whose lookup finds nothing. Receivers should allow at most 2.
- Broken links: an include or redirect to a name without an SPF record, a loop, and
mxterms with more than 10 mail servers. - The ending (
-all,~all,?all,+allor none), and what a receiver concludes for a server you did not list. We replay the evaluation with the address192.0.2.1, which belongs to a range reserved for documentation (RFC 5737), so no real server of yours has it. - Terms the standard advises against:
ptrand the%{p}macro.
What a record check cannot tell you is whether a given message passed SPF: that depends on the server it came from. We send no email; the whole check is DNS lookups through a recursive resolver, and every answer is in the Raw evidence panel under the result.
How to read the SPF record check
The panel at the top of the result is the verdict: a colored icon and a short label. Beside it, a short reading such as 3 of 10 DNS lookups · ~all gives the lookup count and how the record ends. Below come the record as published, the count with what each term costs, the void lookups, the ending in plain words, and the includes as receivers follow them. Each finding links to its explanation on this page.
Pass: receivers can evaluate your record
There is one record, its syntax is valid everywhere, it stays within 10 DNS lookups and 2 void lookups, and it ends with ~all or -all, so mail from servers you did not list does not pass. Pass says the record works; whether it lists every service that really sends your mail only you can tell.
Warning: SPF works, but not as well as it could
The record ends in ?all or has no ending at all; it uses ptr or %{p}; it has a term that finds no records; it is long; or a problem shows up only in a part of the tree built from the sending server's address, so it may hit some senders and not others. Each is explained below.
Fail: receivers get a permanent error, or anyone may pass
There is no SPF record; there are two; a term has a syntax error; the record needs more than 10 DNS lookups or more than 2 void lookups; an include or redirect points to a name without an SPF record; or the record lets any server pass (+all, an include that ends in +all, a network like 0.0.0.0/0). In the first cases receivers get a permanent error (permerror) instead of pass, and under DMARC SPF then counts as not passed.
Could not check
A DNS lookup the verdict depends on did not get a usable answer: it timed out, the server reported a failure (SERVFAIL) or refused. A receiver would call that a temporary error (temperror). We stop a check after 20 seconds and report it the same way. This says nothing about whether your record is correct. We never turn a missing answer into a pass or a fail. Try again in a minute; if it stays, the name servers of the domain or of one of its includes may be unreachable.
Could not check: a fault on our side
Rarely, the result says the check could not be completed because of an internal error. That is a fault in our software, not a finding about your domain and not a network problem, so trying again will most likely give the same result. Please write to support@mxverdict.com with the address of the result page, and we will fix it.
No SPF record
None of the domain's TXT records starts with v=spf1. Receivers then have no way to tell your servers from anyone else's, and Gmail and Yahoo ask every sender for SPF or DKIM. The result is Fail. If the domain sends no email, publish v=spf1 -all, which says no server may send as it (RFC 7208 §10.1.2). If it does, see how to publish a record. A record pasted with curly quotes around it, or with a space before v=spf1, does not count either: receivers look only for texts that start exactly with v=spf1.
More than one SPF record
A domain may have only one record that starts with v=spf1 (RFC 7208 §3.2). With two, receivers do not pick one: every SPF check ends in a permanent error, which is Fail. It usually happens when a new service's record is added next to the old one instead of into it. Merge them: one record with the senders of both and one ending. The fix in the result gives the steps, and a merged record when one can be built. When the name you include has two records, only its owner can fix that.
Syntax errors and look-alike records
One invalid term makes receivers treat the whole record as broken, before they look anything up (RFC 7208 §4.6): Fail. The finding names the term. Common causes: a hostname after ip4:, a typo in a mechanism (inlcude:) or a space inside a term (include: _spf.google.com). A long record split into several strings is fine: receivers join them without spaces (RFC 7208 §3.3), so a space must sit inside a string, not between two.
A Warning for a TXT record that looks like SPF but does not start exactly with v=spf1 (a leading space, v=spf1include:): receivers ignore it. Also a Warning: a modifier receivers do not know, often a typo of redirect= or a second v=spf1, and a record over 450 characters, which risks not fitting in one DNS answer (RFC 7208 §3.4). A target that is not a usable domain name is a Fail, because some receivers stop with an error on it and others skip the term.
The 10 DNS lookup limit
Receivers count the terms that need a DNS lookup while they evaluate your record: include, a, mx, ptr, exists and redirect, including every one inside the records you include. With more than 10, they stop with a permanent error (RFC 7208 §4.6.4), and the result is Fail. ip4, ip6 and all cost nothing. The table “What each term costs” shows where your lookups go: an include costs one for itself plus what its record needs.
When only a part of the tree built from the sending server's address pushes the count over 10, some senders get the error and others do not: Warning. When part of the tree could not be read, the count is a lower bound and the result is Could not check. The same include listed twice costs twice (Warning). See how to get back under the limit.
Void lookups
A void lookup is a term whose DNS lookup finds no records: an a: host that no longer exists, an include of a deleted domain, an mx of a domain without MX. Such a term can never match. Receivers should stop with a permanent error after 2 of them (RFC 7208 §4.6.4), so three are a Fail, one or two a Warning. Some receivers also count mail servers without an address, or an a term without an address of the sender's type (IPv4 or IPv6); where that changes the outcome, the finding says so.
How the record ends: -all, ~all, ?all or +all
The last term says what happens to mail from servers you did not list. -all (fail) asks receivers to reject it and ~all (softfail) to treat it as suspicious without rejecting it on SPF alone (RFC 7208 §8.5); both are Pass. With -all, some receivers apply SPF before DMARC and may reject a forwarded message that your DKIM signature would have let pass DMARC (RFC 9989 §7.1).
?all (neutral) gives no instruction, and a record with neither all nor redirect= ends as if it said ?all (RFC 7208 §4.7): Warning. +all, or a bare all, lets every server in the world pass SPF as your domain: Fail, and so does an include of a record that ends in +all and a network that covers every address. Terms after all are never read (RFC 7208 §5.1), which is a Warning.
Includes: missing records and loops
include: asks the receiver to evaluate another domain's record, usually your mail provider's. If that name has no SPF record, receivers stop with a permanent error (RFC 7208 §5.2): Fail. It happens when a provider changes its include name or a service you stopped using removes its record. Take the current value from the provider's help pages, or remove the include if the service no longer sends for you. An include that leads back to a record already being evaluated is a loop, also Fail. An included record that ends in -all is normal: it only means “not one of our servers”, and evaluation goes on with your next term.
Redirect
redirect= hands the whole decision to another domain's record, for domains that share one policy. If that name has no SPF record, receivers stop with a permanent error (RFC 7208 §6.1): Fail. A redirect in a record that also has all is ignored (RFC 7208 §5.1), which is a Warning: remove one of the two.
mx terms with too many mail servers
Each mx term may lead to at most 10 mail server names; above that, receivers stop with a permanent error (RFC 7208 §4.6.4): Fail. List the sending servers with ip4: and ip6: instead. An mx pointing to a domain that accepts no mail (null MX) can never match and only costs a lookup: Warning.
The ptr mechanism
ptr matches a server by its reverse DNS name. RFC 7208 §5.5 says it should not be published: it is slow, less reliable when DNS fails, and loads the reverse DNS servers. The result is a Warning. Replace it with the servers' addresses in ip4: and ip6:, or with a: and their host name.
Macros and sender-dependent parts
Macros such as %{i} (the sending server's address) build a name from the message being checked, so part of the record differs for every sender. We evaluate those parts with our test sender and say so; that note is marked Pass. A problem found only there is a Warning, because real senders may get a different result. The %{p} macro should not be published (RFC 7208 §7.3): Warning.
Lookups that failed
The TXT lookup of your domain, of an include or of an a, mx or exists target got no usable answer. A receiver would return a temporary error (temperror) and may ask the sender to try later. The result is Could not check, and the lookup count is a lower bound until every part is read. The finding names the lookup; its full answer is in the raw evidence.
What a receiver concludes for other servers
The finding “A receiver checking mail from a server you did not authorize would get …” replays the evaluation in order, as a receiver does, for the test address 192.0.2.1. With a sound record that is fail or softfail. If our test address passes, the record lets far more servers send than it should, for example through a very wide network or an exists term that matches everything: Fail. If it passes only because the record lists a range reserved for documentation, such as 192.0.2.0/24, the record was probably copied from an example: Warning.
How to publish or fix an SPF record
Most problems come with a fix in the result, often the record to publish. The same rules hold at every DNS provider:
- List every service that sends mail with your domain: your mailbox provider, newsletter tool, CRM, help desk, website and billing system. A service you leave out fails SPF.
- Keep one record. Edit the existing
v=spf1record; never add a second one. - Publish it as a TXT record at the domain itself (host
@in most DNS dashboards), at the DNS provider your domain's NS records point to. The steps for Cloudflare, GoDaddy and Namecheap are in the SPF generator's guide; the SPF generator builds the record from a list of your services. - End it with
~allwhile you are still finding every sender;-allonce the list is complete (see how the record ends). - Check again here. A result is reused for 60 seconds, so wait a minute after publishing.
Google Workspace, Microsoft 365 and sending services
What each provider documents for SPF (read in their help pages in September 2026):
| Provider | What goes into SPF |
|---|---|
| Google Workspace | include:_spf.google.com |
| Microsoft 365 | include:spf.protection.outlook.com |
| Zoho Mail | include:zohomail.com; check the value in your Zoho admin console, it can depend on the data center |
| SendGrid | Nothing in your main record: domain authentication sets SPF on a return-path subdomain of yours (such as em1234.example.com) with the records SendGrid gives you |
| Mailgun | include:mailgun.org on the domain you added to Mailgun, often a subdomain such as mg.example.com |
| Amazon SES | Nothing by default (SES uses its own return-path domain); with a custom MAIL FROM subdomain, include:amazonses.com on that subdomain |
A domain that sends through both Google Workspace and Microsoft 365 publishes one record with both:
v=spf1 include:_spf.google.com include:spf.protection.outlook.com ~allHow to get back under 10 DNS lookups
In this order, safest first:
- Remove includes of services that no longer send your mail. Check before you remove one: your DMARC reports list every server that sends in your name (open them in the DMARC report analyzer). Removing an include of a service that still sends makes its mail fail SPF.
- Remove what never matches: the void lookups and duplicate includes the result lists.
- Move services that do not need your main record. SendGrid and Amazon SES can send with a return-path on a subdomain of yours, which gets its own SPF record and its own 10 lookups. A newsletter can be sent from a subdomain such as
news.example.com. - Replace
aandmxwith addresses for your own servers:ip4:andip6:cost no lookup (RFC 7208 §10.1.2 prefers them).
Replacing a provider's include with the addresses behind it (“flattening”) also brings the count down, but it breaks without warning when the provider changes its addresses, and its mail then fails SPF. If you do it, repeat it whenever the provider's record changes.
SPF lookup from the command line
An SPF record is an ordinary TXT record, so any DNS tool shows it. With dig on macOS or Linux, or nslookup on Windows:
dig TXT example.com +short
nslookup -type=TXT example.com 1.1.1.1On September 28, 2026 our own domain returned three TXT records, one of them SPF:
$ dig TXT mxverdict.com +short
"v=spf1 include:_spf.google.com ~all"
"google-site-verification=65IxnQ-_-iFFFZReESC5O04w-sGPOTsDii3lzf2XTQM"
"google-site-verification=isjj4dUZKVqHJVZCmomF61xFy_90caXovHs87zkNzpw"To see what an include adds, look up its name the same way:
$ dig TXT _spf.google.com +short
"v=spf1 ip4:74.125.0.0/16 ip4:209.85.128.0/17 ip6:2001:4860:4864::/56 ip6:2404:6800:4864::/56 ip6:2607:f8b0:4864::/56 ip6:2800:3f0:4864::/56 ip6:2a00:1450:4864::/56 ip6:2c0f:fb50:4864::/56 ~all"A command-line lookup shows one record at a time: it does not follow includes, count lookups or tell a permanent error from a working record. That is what the checker above does. Any TXT record by name can also be seen with the TXT record lookup.
Frequently asked questions
How do I check my SPF record?
Enter your domain in the form at the top of this page. The checker looks up the TXT record that starts with v=spf1, follows every include, counts the DNS lookups and tells you what to fix. A subdomain that sends mail, such as news.example.com, has its own record and is checked on its own. From your own computer, run dig TXT example.com +short; see the command line.
Does SPF protect the From address?
Not by itself. SPF checks the envelope sender (Return-Path) and the server's HELO name, which can differ from the From address people see. DMARC ties them together: it passes only when SPF or DKIM passes for a domain that matches the From domain. Check that part with the DMARC checker.
Why does SPF pass but DMARC fail?
Because SPF passed for another domain. Many services send with their own return-path, such as a subdomain of amazonses.com, so SPF passes for their domain, not yours, and does not count for DMARC. Set up a custom return-path (MAIL FROM) domain under your own domain at the service, or DKIM signing with your domain, which DMARC accepts just as well. The DKIM checker shows whether your key is published.
What does SPF permerror mean?
A permanent error: the receiver could not evaluate your record at all, because of two records, a syntax error, more than 10 DNS lookups, more than 2 void lookups or an include without a record. For your mail it is as bad as having no SPF, and under DMARC SPF counts as not passed. Every one of these causes is a Fail here, with the term that causes it.
Do I need SPF if I have DKIM?
Publish both. Gmail and Yahoo ask every sender for SPF or DKIM, and Microsoft asks senders of 5,000 or more messages to Outlook.com for both to pass (their rules). Forwarded mail usually fails SPF while its DKIM signature stays valid (RFC 9989 §7.4), and SPF covers mail a service sends without signing it for your domain. With both, one can carry DMARC when the other fails.
How long does an SPF record change take?
As soon as your DNS host serves the new record, receivers that have not looked it up recently see it. Those that have keep the old answer until its TTL runs out. Our own result for a domain is reused for 60 seconds, so give it a minute between checks. To see what several public resolvers return right now, use the DNS propagation checker with the record type TXT.
Page updated .