SPF checker

Check an SPF record

See whether a domain authorizes its senders correctly, and whether the record stays within SPF's hard limit of 10 DNS lookups.

An SPF record is a DNS TXT record listing which servers may send mail using your domain. A receiving server looks it up, compares the connecting IP against the list, and returns pass or fail. It breaks most often by exceeding 10 DNS lookups, by publishing two SPF records, or by ending in a qualifier too weak to mean anything.

How to read your result

The checker shows three things, and they fail independently — a record can be syntactically perfect and still be useless.

  • Published record. The raw TXT value found at the domain apex. If this is empty, no SPF exists and every receiver treats your mail as unauthorized by SPF.
  • DNS lookups. How many of SPF's budget of 10 your record consumes. Highlighted mechanisms are the ones that cost a lookup: include, a, mx, ptr, exists and redirect. Over 10 and evaluation returns permerror, which most receivers treat as a failure.
  • Mechanisms. Each entry in evaluation order, with its qualifier. Order matters: the first match wins, so anything after an all is never reached.

What the qualifiers mean

Every mechanism carries a qualifier, shown before it. Omitted means +. Only the one on the final all usually matters, because that is the case that decides unmatched mail.

QualifierResultWhat receivers typically do
+PassAccept as authorized.
-FailReject or bin. The strongest statement you can make.
~SoftfailAccept but mark suspicious. Useful while you are still finding senders.
?NeutralNothing. Equivalent to publishing no opinion at all.

The four most common failures

Exceeding the 10-lookup limit

This is the one that catches nearly everyone, because it arrives by accident. Every SaaS sender you add contributes an include, and each of those can nest further includes that count against your budget, not theirs. Four vendors is often enough to breach it.

The fix is not to remove senders. Flatten what is stable — replace an include whose IPs rarely change with the ip4 ranges it resolves to — and drop mechanisms for services you no longer use. Audit the list rather than trimming blindly: a flattened include silently breaks when the vendor renumbers.

Two SPF records on the same domain

Publishing two v=spf1 records is a permerror, not a merge. Receivers do not pick the more permissive one; the whole evaluation fails. It usually happens when a second vendor's setup guide is followed literally after the first.

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

Right — one record, both senders:
"v=spf1 include:_spf.google.com include:sendgrid.net ~all"

Ending in +all, or in nothing at all

The final mechanism decides what happens to mail that matched nothing. +all authorizes the entire internet to send as your domain, which is worse than having no record. Omitting a final all leaves the result neutral, which receivers treat as roughly equivalent to no policy.

Use -all (hard fail) once you are confident the list is complete, or ~all (soft fail) while you are still finding senders. Both are real answers; ?all is not.

Relying on ptr

The ptr mechanism is deprecated by RFC 7208 and some receivers ignore it outright. It is slow, it depends on reverse DNS you may not control, and it costs a lookup. Replace it with explicit ip4 or ip6 ranges.

A worked example

A record for a domain sending through Google Workspace and one marketing platform:

v=spf1 include:_spf.google.com include:sendgrid.net ip4:198.51.100.25 -all
  • v=spf1 — version tag; must be first and must appear exactly once.
  • include:_spf.google.com — one lookup, plus the lookups inside Google's own record.
  • include:sendgrid.net — one lookup, plus SendGrid's nested includes.
  • ip4:198.51.100.25 — a self-hosted server. Costs no lookup, which is why literal addresses are the cheapest way to stay under the limit.
  • -all — everything else fails. Safe here only because every legitimate sender above is accounted for.

After you change the record

SPF lives in a TXT record at the domain apex — the domain itself, not a _spf subdomain. Publish it wherever your authoritative DNS is hosted, which is often your registrar but may be your CDN or cloud provider if you have delegated the zone.

Changes are not instant. Receivers cache the old record for as long as its TTL says, so a 3,600-second TTL means up to an hour before every receiver sees the new value. If you are about to make a series of changes, lower the TTL first, wait for the old one to expire, then edit — and raise it again when you are done.

Re-run the check above afterwards to confirm the record you published is the record the world resolves. That is not the same question as whether your DNS panel saved it: a typo, a stray quote or a second record added by a vendor's wizard all look fine in the editor and wrong from outside.

Subdomains do not inherit it

An SPF record on example.com says nothing about mail.example.com. Each sending subdomain needs its own record, and a subdomain with none is unauthorized by SPF regardless of what the parent publishes. If you send from a subdomain — many platforms default to one — check it separately.

The exception is DMARC, which does apply down the tree via the parent's policy and its sp= tag. That asymmetry catches people out: DMARC inherits, SPF does not.

SPF alone will not protect your domain

SPF authorizes the envelope sender, not the From: header a recipient actually sees, so it can pass while the visible address is forged. It also breaks on forwarding, because the forwarding server is not in your record. That is what DKIM and DMARC exist to cover: DKIM survives forwarding, and DMARC ties the result back to the visible domain.

Related checks

  • DMARC checker — the policy that gives SPF and DKIM their teeth.
  • DKIM checker — signature-based authentication that survives forwarding.
  • TXT lookup — see every TXT record on the domain, including duplicate SPF.
  • MX lookup — confirm where the domain receives mail.
  • Full domain check — SPF, DKIM, DMARC, MX and more in one pass.

Every mechanism and modifier, in full →