An include target publishes no SPF record
One of your include: targets does not publish an SPF record. The recursive evaluation that include triggers has nothing to evaluate, so the whole check returns permerror — your other senders stop being evaluated too. This page covers why a target goes empty, how to see what an include actually resolves to, and how it differs from a lookup that merely timed out.
Measured 2026-09-08: 4 of 320 audited domains (1.25%) named an include target that publishes no SPF record. These are domains someone had a reason to check, so this is an upper bound and not an internet-wide rate — method, window and exclusions in SPF Observatory 2026.
What was observed
An include: in your record names a host, and a TXT lookup on that host returns nothing beginning v=spf1.
What causes it
These are protocol and measurement causes only. We do not speculate about what a receiver did with the result.
- A typo in the include target.
- The vendor changed its SPF hostname and the old one stopped publishing.
- An inbound hostname was used where the vendor's SPF include belongs —
mail.vendor.comrather thanspf.vendor.com. - The vendor was retired and its zone no longer answers.
How to verify it yourself
- See what the include actually resolves to
dig +short TXT _spf.google.com - An empty answer is the fault; a record starting v=spf1 is fine
dig +short TXT spf.example-vendor.com
Check this record Reads the live record and counts every DNS lookup it costs.
The safe fix, and what it can break
Correct the target, or remove it if you no longer send through that vendor. Get the current include from the vendor's own documentation rather than from an older copy of your record — that is where the stale value came from.
What can break: Removing an include removes every sender it covered. If you are unsure whether the vendor is still in use, check DMARC reports for its sources before deleting rather than after.
Examples
v=spf1 include:spf.retired-vendor.example ~allv=spf1 include:_spf.google.com include:spf.protection.outlook.com include:sendgrid.net ~allWhat the standard says
RFC 7208 §5.2: “The "include" mechanism triggers a recursive evaluation of check_host()”
What does “include target has no SPF record” mean and why is it PermError?
The include triggers a recursive evaluation (RFC 7208 §5.2). If the target publishes no record, that recursion cannot reach a result, and the parent evaluation returns permerror rather than ignoring the line.
What are the common causes?
A typo; a vendor that changed its SPF hostname; an inbound mail hostname used where the vendor's SPF include belongs; or a vendor you stopped using whose zone no longer answers.
How do I see what an include resolves to?
dig +short TXT <target>. An empty answer is the fault. Note the TXT: without it dig returns the CNAME or A record and tells you nothing about SPF.
Where do I find the correct include for the major providers?
Each vendor's own current documentation — Google, Microsoft, SendGrid, Mailchimp, Brevo and HubSpot all publish theirs. We deliberately do not reprint the values here: a stale include copied from a third-party page is how this fault appears in the first place.
How is this different from a lookup timeout?
A timeout is temperror: the answer could not be obtained right now, and a retry may succeed. An empty answer is permerror: the record was obtained and it says nothing. Retrying will not fix it.
How do I fix it and re-check?
Correct or remove the target, wait for the previous answer's TTL to expire, then re-run the dig above and the checker linked on this page.
What we do not claim
We report what your DNS publishes and what an evaluator would return from it. We do not state what any mailbox provider will do with that result: those decisions are theirs, they are not published, and we cannot measure them from here.
Reviewed by Venkat Nookala, last reviewed 2026-09-08.