Google Workspace needs exactly one thing from SPF: authorization for the IP ranges Google sends your mail from. Those ranges live behind a single include, so the correct record is short. Almost every Google Workspace SPF problem is not the Google part — it is a second record, a stale record, or a host field that put the TXT at the wrong name.
What is the correct record?
Type: TXT
Host: @ (some panels want the bare domain, or leave blank)
TTL: 3600
Value: v=spf1 include:_spf.google.com ~allNothing else is required. You do not need to add a, you do not need mx, and you must not add individual Google IP addresses — Google changes them, and the include is what keeps you current. Verify what that include actually authorizes at any time:
dig +short TXT _spf.google.com
# "v=spf1 ip4:74.125.0.0/16 ip4:209.85.128.0/17 ip6:2001:4860:4864::/56
# ip6:2404:6800:4864::/56 ip6:2607:f8b0:4864::/56 ip6:2800:3f0:4864::/56
# ip6:2a00:1450:4864::/56 ip6:2c0f:fb50:4864::/56 ~all"include:_spf.google.com costs exactly one of your ten SPF DNS lookups. It is one of the cheapest vendor includes there is, which leaves nine for everything else.Why can you only have one SPF record?
RFC 7208 is explicit: if a domain has more than one TXT record starting with v=spf1, the evaluation result is permerror. Not "the receiver picks the best one", not "they merge" — a hard failure that makes both records useless. This is the single most common way a working Google Workspace setup gets broken, because most DNS panels are happy to let you add a second TXT record with no warning at all.
; BROKEN — two v=spf1 records, permerror
example.com. TXT "v=spf1 include:_spf.google.com ~all"
example.com. TXT "v=spf1 include:sendgrid.net ~all"
; CORRECT — one record, both senders merged
example.com. TXT "v=spf1 include:_spf.google.com include:sendgrid.net ~all"Other TXT records at the same name are fine and expected — domain verification strings, DKIM keys on their own subdomains, Google site verification. Only the v=spf1 ones must be unique. Use the TXT record lookup to see everything published at your apex in one view.
How do you merge Google with SendGrid, Mailgun, or a CRM?
Take the mechanisms out of each vendor's suggested record, drop their v=spf1 prefix and their trailing all, and put them in one record with a single all at the end. Order among include: terms does not change the result, but putting your primary mail platform first makes the record easier to read.
| Also sending through | Add this mechanism | DNS lookups it costs |
|---|---|---|
| Google Workspace | include:_spf.google.com | 1 |
| Microsoft 365 (hybrid or migration) | include:spf.protection.outlook.com | 1 |
| SendGrid | include:sendgrid.net | 2 — it nests ab.sendgrid.net |
| Mailgun (global record) | include:mailgun.org | 5 — it nests four more records |
| Amazon SES | include:amazonses.com | 1 |
| Mailchimp (Mandrill transactional) | include:spf.mandrillapp.com | 1 |
| Salesforce | include:_spf.salesforce.com | 2 — contains an exists: macro |
v=spf1 include:_spf.google.com include:sendgrid.net include:amazonses.com ~allIf merging pushes you past ten, do not start deleting at random. Move the bulk stream onto its own subdomain with its own Return-Path and its own SPF record — the approach walked through in SPF PermError: too many DNS lookups. And check whether the vendor needs to be in SPF at all: a vendor that bounces to its own domain and signs with a DKIM key on yours satisfies DMARC through DKIM alignment alone.
Should you end with ~all or -all?
Google's own domain publishes v=spf1 include:_spf.google.com ~all, and softfail is the right starting point for almost everyone. It tells receivers "this is probably not us" without asking them to reject outright, which matters while you are still discovering forgotten senders. Move to -all once DMARC aggregate reports show a clean, complete inventory of your sending sources. The trade-offs are covered in SPF ~all vs -all.
How do you verify it?
# The record itself
dig +short TXT example.com | grep spf1
# "v=spf1 include:_spf.google.com ~all"
# Exactly one SPF record? Anything other than 1 is a problem.
dig +short TXT example.com | grep -c spf1
# Same query without dig, if you only have host(1)
host -t TXT example.com
# Confirm the include still resolves (a void lookup here breaks SPF)
dig +short TXT _spf.google.comA blank result from the first command usually means the record went in at the wrong name. Panels differ: some want @, some want the bare domain, some want the field left empty, and some silently append your domain to whatever you type — which turns example.com into example.com.example.com. If dig TXT example.com is empty, try dig +short TXT example.com.example.com and you will often find your record sitting there.
After DNS looks right, send a message from a Workspace mailbox to an external address you control and read the received copy's Authentication-Results header. You want spf=pass with an smtp.mailfrom on your domain. Paste the full headers into the email header analyzer if you would rather not parse it yourself, and run the deliverability test to see SPF, DKIM, DMARC, MX, and PTR together.
Common mistakes
- A second SPF record left behind by an old host or a vendor onboarding wizard. Always grep for the count, not just the presence.
- Copying Google IPs directly into your record instead of using the include. They change; your record does not follow.
- Adding SPF for a subdomain when mail comes from the apex. SPF is checked against the MAIL FROM domain, so publish it where the bounces come from.
- Quoting problems. Some panels want the value with surrounding quotes and some add them for you. If
digshows"\"v=spf1 ...\"", you have double quotes and the record will not parse. - Leaving `ptr` in a legacy record. It costs a lookup, it is slow, and RFC 7208 advises against publishing it.
- Expecting instant results. The previous record is cached for its TTL. Lower the TTL before a planned change — see lower your TTL before a DNS migration.