# SPF record syntax and examples

URL: https://iblockspam.com/blog/spf-record-syntax-examples
Last updated: 2026-10-09
Published: 2026-10-09
Topic: SPF, DKIM & DMARC
Author: iBlockSpam Team

> SPF record syntax explained: mechanisms, qualifiers and modifiers, with copy-ready examples for Microsoft 365, Google Workspace, subdomains and parked domains.

## Short answer

An SPF record is one TXT record that starts with v=spf1, lists who may send mail for your domain using mechanisms such as include, ip4 and mx, and ends with an all mechanism. For Microsoft 365 only: v=spf1 include:spf.protection.outlook.com -all. For a domain that sends no mail: v=spf1 -all.

SPF is a single DNS TXT record that lists the servers allowed to send mail using your domain. The syntax is short, but small mistakes break it completely. This guide explains each part of the record, gives working examples for common setups, and lists the mistakes we see most often. New to SPF? Start with [what SPF is and how it works](https://iblockspam.com/blog/what-is-spf).

## What does an SPF record look like?

Here is a typical record:

```
example.com.  3600  IN  TXT  "v=spf1 ip4:203.0.113.10 include:spf.protection.outlook.com -all"
```

Read it left to right:

- `v=spf1` marks this TXT record as SPF. It must come first.
- `ip4:203.0.113.10` allows one server by IP address.
- `include:spf.protection.outlook.com` allows every server in Microsoft 365's SPF record.
- `-all` says everything else fails.

Receivers check the IP address of the server that connected to them against this list, in order, and stop at the first match ([RFC 7208](https://www.rfc-editor.org/rfc/rfc7208.html)). SPF checks the **envelope sender** (the `MAIL FROM` address, often shown as Return-Path), not the From address people see. Linking the two is DMARC's job.

## What does each SPF mechanism do?

Mechanisms are the terms that match a sending IP. They're defined in [section 5 of RFC 7208](https://www.rfc-editor.org/rfc/rfc7208.html#section-5).

| Mechanism | Example | Matches when | DNS lookup? |
|---|---|---|---|
| `ip4` | `ip4:203.0.113.0/24` | The IP is in this IPv4 address or range | No |
| `ip6` | `ip6:2001:db8::/32` | The IP is in this IPv6 address or range | No |
| `include` | `include:_spf.google.com` | The other domain's SPF record passes for this IP | Yes |
| `a` | `a` or `a:web.example.com` | The IP is one of that host's A/AAAA addresses | Yes |
| `mx` | `mx` | The IP belongs to one of the domain's MX hosts | Yes |
| `exists` | `exists:%{i}.rbl.example.net` | A lookup of the built name returns any A record | Yes |
| `ptr` | `ptr` | Reverse DNS matches the domain. Don't use it | Yes |
| `all` | `-all` | Always matches. Goes last | No |

Every mechanism marked "Yes" counts toward the limit of **10 DNS lookups** per check, including lookups inside the records you include. Go over and the result is PermError. Our guide to [SPF PermError: too many DNS lookups](https://iblockspam.com/blog/spf-too-many-dns-lookups) covers this in detail.

Anything after `all` is ignored, so `all` must be the last mechanism.

## What do the SPF qualifiers + - ~ ? mean?

Each mechanism can have a qualifier in front. It sets the result when that mechanism matches.

| Qualifier | Name | Result | Typical use |
|---|---|---|---|
| `+` | Pass | Authorized | The default; you rarely write it |
| `-` | Fail | Not authorized | `-all` at the end of a complete record |
| `~` | Softfail | Probably not authorized | `~all` while you're still finding senders |
| `?` | Neutral | No statement | Testing only |

Because `+` is the default, `include:x` means `+include:x`. Never write `+all`; it authorizes every server on the internet.

If no mechanism matches and there's no `all` or `redirect`, the result is neutral, as if the record ended in `?all`. RFC 7208 recommends always ending with an explicit `all` or a `redirect`.

## What do the redirect and exp modifiers do?

Modifiers use `=` rather than `:`.

- **`redirect=domain`** hands the whole check to another domain's SPF record when nothing else matches. It's useful when many domains share one policy, for example `v=spf1 redirect=_spf.example.com`. It's ignored if the record contains `all`, and if the target has no SPF record the result is PermError (RFC 7208, section 6.1).
- **`exp=domain`** points to a TXT record with an explanation string for failed messages. Few receivers show it; most domains don't need it.

`redirect` and `exp` may each appear only once; a duplicate is a PermError (RFC 7208, section 6).

## Which SPF record fits your setup?

Looking for one provider's exact value? See [SPF records by email provider](https://iblockspam.com/spf) for the include each service documents and what it costs in lookups.

### Microsoft 365 only

```
v=spf1 include:spf.protection.outlook.com -all
```

This is the record [Microsoft](https://learn.microsoft.com/en-us/defender-office-365/email-authentication-spf-configure) gives for domains where Microsoft 365 is the only sender. Our [Microsoft 365 SPF record page](https://iblockspam.com/spf/microsoft-365) shows the include's measured lookup cost, and the [Microsoft 365 platform page](https://iblockspam.com/platforms/microsoft-365) covers filtering.

### Google Workspace only

```
v=spf1 include:_spf.google.com ~all
```

This is the record from [Google's SPF setup guide](https://knowledge.workspace.google.com/admin/security/set-up-spf), which recommends `~all`. Changing it to `-all` is valid once you're sure Google is your only sender. Our [Google Workspace SPF record page](https://iblockspam.com/spf/google-workspace) has the details, and the [Google Workspace platform page](https://iblockspam.com/platforms/google-workspace) covers filtering.

### Several senders on the main domain

```
v=spf1 ip4:203.0.113.10 include:spf.protection.outlook.com include:mailer.example.net -all
```

Microsoft 365 for staff, an on-premises server or website at one IP, and one third-party service. Each new service adds an `include` to the **same** record. Never create a second record.

### Bulk mail on a subdomain

```
example.com.       TXT  "v=spf1 include:spf.protection.outlook.com -all"
news.example.com.  TXT  "v=spf1 include:mailer.example.net -all"
```

Microsoft recommends putting services you don't directly control, such as newsletter tools, on a subdomain. The subdomain needs its own record, and it gets its own 10-lookup budget.

### Parked or non-sending domain

```
v=spf1 -all
```

Microsoft gives this exact record for parked domains: no server is authorized. Pair it with a DMARC record such as `v=DMARC1; p=reject;` so the visible From address is protected too ([RFC 9989](https://www.rfc-editor.org/rfc/rfc9989.html)). Do the same for any defined subdomain that never sends mail.

### Domain with an inbound filtering service

```
v=spf1 include:spf.protection.outlook.com -all
```

If a filtering service only **receives** your mail, nothing changes in SPF. Microsoft's own guidance for an MX that points to third-party filtering uses the standard Microsoft 365 record and says to add the filter only if outbound mail goes through it.

## What are the most common SPF mistakes?

| Mistake | What happens | Fix |
|---|---|---|
| Two TXT records starting with `v=spf1` | PermError for every message (RFC 7208, section 4.5) | Merge into one record |
| More than 10 DNS-querying terms | PermError | Remove unused senders, use subdomains |
| `include=domain` instead of `include:domain` | Syntax error | Use a colon |
| Space after the colon | Syntax error | `include:spf.protection.outlook.com` |
| Trailing dot after a domain | RFC 7208 says it shouldn't be published (receivers must still accept it); Microsoft lists it as a common mistake | `include:spf.protection.outlook.com` |
| Using `ptr` | Slow, unreliable; RFC 7208 says it shouldn't be published | Use `ip4`, `ip6` or `include` |
| `+all` | Authorizes everyone | Use `-all` or `~all` |
| `?all` in production | SPF says nothing useful | Use `~all` or `-all` |
| Mechanisms after `all` | Ignored | Put `all` last |
| `include` of a domain with no SPF record | PermError | Remove it or fix the target |
| Using the obsolete SPF record type | Ignored; SPF must be published as TXT | Publish TXT only |
| Adding inbound-only services | Wastes lookups | Only list services that send |

Microsoft's troubleshooting guide lists the colon, space and trailing-dot errors as common syntax mistakes.

This isn't rare. In our [October 2026 scan of the Tranco top 1,000 domains](https://iblockspam.com/research/email-security-top-1000), 4 domains published more than one SPF record and 22 went over the 10-lookup limit.

### ~all vs -all: which should you use?

Both stop SPF from vouching for unknown servers. The difference is how strongly.

- `-all` (fail) says unlisted servers aren't authorized. Microsoft recommends it for Microsoft 365 domains with DKIM and DMARC, because DMARC then decides what happens to failures, and DMARC reports let you check the results.
- `~all` (softfail) says they probably aren't. Google's guide recommends it.

Under DMARC, both count as an SPF fail. In practice, the deciding factor is your DMARC policy, not the qualifier. Of the 764 top-1,000 domains in our scan that publish SPF, 438 end in `-all`, 274 in `~all`, 19 in `?all`, and 33 use `redirect`.

### Long records and multiple strings

A single TXT string is limited to 255 characters. Longer records can be split into several quoted strings in one TXT record, which receivers join with **no** added space:

```
"v=spf1 include:spf.protection.outlook.com include:mailer.example.net "
"include:crm.example.org -all"
```

Note the space at the end of the first string. RFC 7208 also recommends keeping the whole record small enough to fit in a 512-byte DNS response.

## How do you write or change your SPF record?

1. **List every service that sends as your domain:** your mailbox platform, website forms, CRM, helpdesk, invoicing and newsletter tools. Google's [sender guidelines](https://support.google.com/mail/answer/81126) say missing senders are more likely to be marked as spam.
2. **Get each vendor's documented `include` or IP range.** Don't guess.
3. **Move bulk senders to a subdomain** where you can.
4. **Build one record**, starting with `v=spf1` and ending with `~all` or `-all`.
5. **Check it** with the [SPF Checker](https://iblockspam.com/tools/spf-checker) for syntax and lookup count.
6. **Replace the old record** at your DNS host. Edit it; don't add a second one.
7. **Test** by sending from each service to an outside mailbox and checking `spf=pass` in the headers.
8. **Add DKIM and DMARC.** Google requires SPF or DKIM from all senders, and SPF, DKIM and DMARC from bulk senders.

## Next steps

- Run your domain through the [SPF Checker](https://iblockspam.com/tools/spf-checker) to see your current record, lookup count and any syntax problems.
- Building a record from scratch? The [SPF Record Generator](https://iblockspam.com/tools/spf-generator) assembles one from your mail services and estimates its lookups. For the exact include each service documents, see [SPF records by email provider](https://iblockspam.com/spf).
- Publish `v=spf1 -all` plus a reject DMARC policy on every domain you own that doesn't send mail.
- Check your DMARC record with the [DMARC Checker](https://iblockspam.com/tools/dmarc-checker); our [DMARC record examples](https://iblockspam.com/blog/dmarc-record-examples) show what to publish.
- If you want to know when someone changes your SPF record, iBlockSpam [domain monitoring](https://iblockspam.com/features/domain-monitoring) sends drift alerts.

Browse our other [SPF, DKIM and DMARC guides](https://iblockspam.com/blog/topic/authentication).

## Frequently asked questions

### Should I use ~all or -all?

Both are valid. Microsoft recommends -all for Microsoft 365 domains that also use DKIM and DMARC. Google recommends ~all in its setup guide. Once your record lists every real sender and DMARC is in place, -all is the clearer statement. If you're still discovering senders, ~all is the gentler starting point.

### Can I have two SPF records?

No. RFC 7208 says a domain must not publish more than one SPF record, and receivers return PermError if they find two. Merge all your senders into one record that starts with v=spf1. Other TXT records, such as domain verification codes, can stay alongside it.

### Does an SPF record cover my subdomains?

No. SPF is checked for the exact domain in the envelope sender, so news.example.com needs its own record. That's useful: each subdomain gets its own 10-lookup budget. DMARC, by contrast, can apply a parent domain's policy to subdomains.

### What should an SPF record look like for a domain that doesn't send email?

Publish v=spf1 -all. It says no server is allowed to send mail using that domain. Add a DMARC record with p=reject as well, because SPF only covers the envelope sender, not the From address people see.

### Do I need to add my spam filter to SPF?

Only if it sends mail for you. An inbound-only filtering service receives your mail and doesn't need to be in SPF. If you use the same provider as an outbound relay, add the include or IP addresses it documents for outbound mail.

## Sources

- [RFC 7208: Sender Policy Framework (SPF)](https://www.rfc-editor.org/rfc/rfc7208.html)
- [RFC 7208, section 5: Mechanism definitions](https://www.rfc-editor.org/rfc/rfc7208.html#section-5)
- [Microsoft Learn: Set up SPF to identify valid email sources for your Microsoft 365 domain](https://learn.microsoft.com/en-us/defender-office-365/email-authentication-spf-configure)
- [Google Workspace Admin Help: Set up SPF](https://knowledge.workspace.google.com/admin/security/set-up-spf)
- [Gmail Help: Email sender guidelines](https://support.google.com/mail/answer/81126)
- [RFC 9989: DMARC](https://www.rfc-editor.org/rfc/rfc9989.html)

## Free tools for this guide

- [SPF Checker](https://iblockspam.com/tools/spf-checker): Count real DNS lookups, find PermErrors, loops and risky "all" settings.
- [SPF Record Generator](https://iblockspam.com/tools/spf-generator): Build a valid SPF record from your mail providers, with a DNS lookup count.
- [DMARC Checker](https://iblockspam.com/tools/dmarc-checker): Check your policy, reporting and the safe path from p=none to reject.
- [Email Health Check](https://iblockspam.com/tools/email-health-check): Grade your domain's MX, SPF, DKIM, DMARC and transport security in one scan.

---

Source: iBlockSpam, https://iblockspam.com/blog/spf-record-syntax-examples (this is a Markdown copy; the HTML page is canonical). Quote with attribution and a link. Site index for AI assistants: https://iblockspam.com/llms.txt
