An SPF record is a single TXT record at the root of your domain. Getting it right is mostly a matter of not forgetting anything that sends mail on your behalf.
1. List everything that sends as you
Go wider than your mailbox provider. Common senders people forget:
- Marketing and newsletter tools (Mailchimp, HubSpot, Brevo)
- Transactional email from your app (SendGrid, Postmark, Amazon SES, Mailgun)
- Helpdesk, CRM and invoicing systems that send "from" your domain
- Your own servers, printers or scanners that relay mail
Each service documents the SPF entry to add, usually an include:.
2. Write the record
Start with v=spf1, add one term per sender, and finish with an all:
v=spf1 include:_spf.google.com include:mailgun.org ip4:203.0.113.10 -all
include:domain— authorise whatever that domain's SPF record authorises.ip4:/ip6:— authorise an address or range directly. Costs no DNS lookups.a/mx— authorise the addresses of your own web or mail hosts.
3. Choose -all or ~all
-all (fail) says anything not listed is unauthorised. ~all (soft fail) says it is probably unauthorised. With a DMARC policy enforcing, receivers act on either, so ~all is a reasonable choice while you are confident but not certain the list is complete. Never use +all, which authorises the entire internet, and avoid ?all, which says nothing.
4. Publish exactly one record
A domain must have one TXT record starting with v=spf1. Two records is a permanent error and SPF fails for everyone. When adding a new service, edit the existing record rather than adding another.
Common mistakes
- More than 10 DNS lookups. Every
include,a,mx,existsandredirectcounts, including the ones nested inside the includes. See fixing too many DNS lookups. - Using
ptr. It is deprecated, slow, and some receivers ignore it. - Terms after
all. Evaluation stops atall, so anything after it never runs. - Typos in an include. An include that points at a domain with no SPF record is a permanent error, not a harmless no-op.
