How to Add an SPF Record to Your Domain

You can do this

SPF lists who is allowed to send email as your domain. It is one TXT record, it is not hard, and most broken SPF setups fail for one of four reasons we can name up front.

SPF has nothing to do with your web server. It lives in DNS, wherever your DNS is hosted.

What SPF is, in one paragraph

SPF is a TXT record on your domain that lists the servers allowed to send email using your domain in the envelope sender. A receiving mail server looks it up, compares it to where the message actually came from, and decides what that means. Without it, anyone can put your domain on an email and nothing contradicts them.

It is defined by RFC 7208. There was once a dedicated SPF DNS record type, type 99. It is deprecated. Use a TXT record. If your DNS host offers an "SPF" record type in a dropdown, it is almost certainly writing a TXT record anyway, but check.

The record goes at the domain itself, not on a subdomain or a made-up hostname. Our SPF glossary entry has the short version if you want it.

The rule that breaks the most domains

One SPF record per domain. Exactly one.

If your domain publishes two SPF records, the result is a permerror. That is a hard failure, not a fallback, and it does not mean "use the better one". Both records are effectively ignored and SPF is broken for your entire domain. This is one of the most common real faults we see, and it happens the obvious way: you added Google, then months later you added a marketing tool, and its setup guide said "add this TXT record" so you did.

The fix is to merge. One record, multiple include mechanisms, one terminal all at the end.

Broken. Two records, permerror, SPF is dead for the whole domain:

  example.com.  TXT  "v=spf1 include:_spf.google.com ~all"
  example.com.  TXT  "v=spf1 include:sendgrid.net ~all"

Correct. One record, both senders, one all:

  example.com.  TXT  "v=spf1 include:_spf.google.com include:sendgrid.net ~all"

The all mechanism is terminal. Anything after it is never evaluated, so it belongs at the end and it appears once.

Building your record

Start from what you actually send with. These are the values we can confirm.

  • Google Workspace: v=spf1 include:_spf.google.com ~all
  • Microsoft 365: v=spf1 include:spf.protection.outlook.com -all. GCC High and DoD use include:spf.protection.office365.us instead, and 21Vianet uses include:spf.protection.partner.outlook.cn.
  • SendGrid: include:sendgrid.net but only when Automated Security is off. With Automated Security on, which is the default, SendGrid authenticates through CNAME records you add during setup and you do not need an include at all. Adding one anyway burns a DNS lookup for nothing. Check the setting before you add it.
  • Your own mail server: use ip4: or ip6: with the sending IP. These cost you nothing against the lookup limit, so they are the cheapest mechanism you have.
  • Mailchimp: we are not publishing an include value. The ones circulating are unconfirmed and likely obsolete now that they sign with their own Return-Path domain. Follow their current setup screen, not a blog post.

The 10 lookup limit

SPF evaluation is capped at 10 DNS lookups. Exceed it and you get a permerror, which is the same hard failure as having two records. Nobody warns you. It just stops working once you add one sender too many.

What costs a lookup: include:, a, mx, exists, and redirect. Worse, they nest. An include: that resolves to a record containing three more includes has spent four of your ten, and you cannot see that from your own record.

What is free: ip4:, ip6:, and all. If you know the IPs, listing them directly costs nothing.

Four or five includes is where domains start dying. If you are near the limit, drop senders you no longer use rather than getting clever.

Subdomains need their own record

A record on example.com does not cover mail.example.com or news.example.com. SPF does not inherit. If a subdomain sends email, it needs its own TXT record at that subdomain.

If a subdomain sends nothing, publish a record saying so. Same for parked domains you own but never send from. It is one line and it closes the door.

Domain or subdomain that never sends email:

  parked.example.com.  TXT  "v=spf1 -all"

For a non-sending domain, -all is the right answer and there is no vendor disagreement about it.

~all or -all, honestly

The last mechanism says what to do with everything not listed. This is where guides get confident and vendors disagree, so here is the actual state of play.

~all is softfail. It means "probably not authorised". -all is fail. It means "not authorised". ?all is neutral and is close to pointless.

Google recommends ~all for Workspace. Microsoft recommends -all, and their reasoning is worth knowing: with DMARC in play, a message that softfails SPF is effectively given a pass on SPF, so if it has no DKIM signature you get less protection than you think you have. That is a real argument, not a style preference.

What we would do: start with ~all while you are still finding senders. Watch your DMARC aggregate reports until you are confident every legitimate sender is accounted for. Then move to -all. Going straight to -all before you know what sends mail for you is how invoices and password resets end up in nowhere.

This is also why SPF alone is not enough. It pairs with DMARC, which is the part that tells you what is happening and gives inboxes a policy to act on.

Where the record goes, and the one mistake everybody makes

SPF is a DNS record, so it goes wherever your DNS is hosted. Your registrar, Cloudflare, your host, Route 53. Your web server has nothing to do with it.

The near universal mistake: most DNS UIs take a relative name and append your zone automatically. For SPF you want the record at the root, which is usually @ or a blank name field. Type example.com in that field and some hosts will happily create example.com.example.com, which resolves for nobody.

Two host specifics worth knowing. On Cloudflare, TXT records are always DNS only and cannot be proxied, so there is no orange cloud to worry about. On Route 53, values must be in double quotes, a single string maxes out at 255 characters, and you leave the name blank for the apex. Route 53 is also the exception to the auto append rule: it takes a fully qualified name.

The direction things are moving

Worth knowing before you build a record you will maintain for years. Vendors are shifting away from "add our include:" toward CNAME delegated Return-Path subdomains. SendGrid Automated Security does this, Mailchimp does this, Amazon SES does this.

It is a better design. Your ten lookup budget stays intact, and the vendor can rotate their own infrastructure without needing you to edit DNS. It also means include values you find in old documentation may simply be wrong now. Treat any vendor include as a verify-at-the-time fact, not something to copy from a three year old answer.

Once your record is live, run a free check to confirm it resolves and parses.

Check your work in seconds

Run your site through our free safety check to confirm the fix is live, and see what else a shopper would notice.

Run a free check

Frequently asked questions

Can I have two SPF records?

No, and this is the single most common SPF fault. Two records produce a permerror, which is a hard failure that breaks SPF for the entire domain. Receivers do not pick the better one. Merge everything into one record with multiple include mechanisms and a single all at the end.

Should I use ~all or -all?

Vendors genuinely disagree. Google recommends ~all for Workspace. Microsoft recommends -all and makes a fair point: DMARC effectively ignores an SPF softfail, so without DKIM you get less protection than you expect. Our advice is to start with ~all, confirm every legitimate sender through DMARC reports, then move to -all.

Does my SPF record cover my subdomains?

No. SPF does not inherit. A record on example.com says nothing about mail.example.com. Any subdomain that sends email needs its own TXT record. Any subdomain that never sends should publish v=spf1 -all.

What is the SPF 10 lookup limit?

SPF evaluation stops after 10 DNS lookups and returns a permerror. The include, a, mx, exists and redirect mechanisms each cost a lookup, and they nest, so one include can consume several. ip4, ip6 and all cost nothing. Most domains hit the wall around four or five includes.

Do I need include:sendgrid.net?

Only if Automated Security is turned off. With it on, which is the default, SendGrid authenticates through CNAME records you add during setup and no SPF include is needed. Adding it anyway spends one of your ten lookups for nothing. Check the setting first.

Where do I add the SPF record if I run my own server?

Wherever your DNS is hosted, which is usually your registrar, Cloudflare, or your host. Your web server is not involved. Put it at the root of the zone, which is normally @ or a blank name. Do not type your full domain into the name field, because most DNS UIs append the zone and you will end up with example.com.example.com.

SPF record on other platforms

Other fixes for A custom site

See the full fix-it matrix →

Prove your site is safe.

Once it is fixed, show it. Get a badge your shoppers can verify, backed by continuous checks. Free to start.

Get started free Run a free check