SPF record present and single
Exactly one SPF TXT record at the apex.
- Severity
- high
- Tier
- Passive: runs on any URL
- Category
- Fix
- Summary below; full runbook in the Fix Kit, Module 00: Foundations
- Id
- spf
What this means
Passing means your domain's apex has exactly one TXT record beginning v=spf1, naming the services allowed to send mail as you. Failing means there is none, so receivers cannot check your mail, or there are two or more, which the standard treats as a permanent error. Two SPF records is the common one: an inbound provider adds one, an outbound provider adds another, and both stay.
How we test it
We run a TXT lookup on the apex of your domain and count the records that contain v=spf1. Exactly one is a pass. Zero, or two or more, is a fail; there is no warn state. This is a passive check, so nothing needs to be set up or verified for us to run it.
Why it matters
Two SPF records equal none; mail from the domain is unauthenticated. Receivers that find two records stop evaluating, so a second record added for a new provider silently undoes the first. In the Module 00 troubleshooting notes, a low deliverability score traces to exactly this: SPF with two records, fixed by merging the includes into one. Unauthenticated mail is the mail that lands in spam, including sign-in codes and receipts.
The fix
Merge every SPF candidate on the apex into one TXT record on @, for example v=spf1 include:_spf.mx.cloudflare.net include:amazonses.com ~all when Cloudflare Email Routing handles inbound and Resend handles outbound, using the include values each provider actually shows, and delete the others. Confirm with dig +short TXT YOUR_DOMAIN | grep -c spf1 returning 1.
Prompt for your AI
Paste this into the coding agent that built the app. It reproduces the finding and stops before changing anything; the fix steps are in the kit.
Do not change any DNS record. Run: dig +short TXT YOUR_DOMAIN and show me the full output. Count the lines that contain v=spf1 and tell me the number. For each SPF line, list its include: entries and its final mechanism (~all, -all or +all). Run: dig +short MX YOUR_DOMAIN and tell me which inbound provider the MX hosts belong to. Run: dig +short TXT resend._domainkey.YOUR_DOMAIN and say whether an outbound provider key is present. Tell me which include values a single merged record would need, and stop before editing anything. Finally run: dig +short TXT YOUR_DOMAIN | grep -c spf1 and show the number. Expected 1; anything else means the finding stands.
Grade your own URL
Every grade lists this check with its evidence for your site. Two free grades a day.