# SPF

SPF is a DNS TXT record on your domain listing the hosts permitted to send mail using it as the **envelope** sender. A receiving server checks the connecting address against that list and gets a pass, a fail or a softer verdict. It authorises a route, not a person, and it says nothing about the `From:` line a reader sees.

- **Status:** Reference
- **Audience:** both, developer
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/technology/spf/

## The record, mechanism by mechanism

```text
example.net.  TXT  "v=spf1 include:_spf.provider.example a:mail.example.net ip4:203.0.113.10 -all"
```

**`v=spf1`** — Version marker. Must be first. A domain must publish at most one SPF record; two is a permanent error, not a merge.
**`include:`** — Import another domain's policy. The usual way a provider is authorised, and the usual cause of the lookup-limit problem below.
**`a` / `mx`** — Authorise the addresses of the domain's own A or MX records. Convenient and each costs a lookup.
**`ip4:` / `ip6:`** — Literal addresses or ranges. Cost no lookups, which makes them the fix when you are close to the limit.
**`-all`** — Hard fail: nothing else is authorised. The intended end state.
**`~all`** — Soft fail: not authorised, treat as suspicious. Reasonable while rolling out; not a destination.
**`?all` / `+all`** — Neutral and pass-everything. `+all` authorises the entire internet and should never be published.

Mechanisms are evaluated left to right and the **first match wins**, so ordering matters: an `include` that matches early stops evaluation before anything after it is considered.

## The ten-lookup limit, and how domains exceed it

Evaluating a record may perform at most **ten** DNS-querying mechanisms. `include`, `a`, `mx`, `ptr`, `exists` and `redirect` each count, and they count **recursively** — an `include` that itself contains three `include`s has spent four. Exceeding the limit is a `permerror`, and a `permerror` is not a fail-open: many receivers treat it as no valid policy at all.

| Mechanism | Lookups | Note |
|---|---|---|
| `ip4:` / `ip6:` | 0 | Free. The lever when you are over budget |
| `a` / `mx` | 1 each | Plus one more per MX host resolved |
| `include:` | 1 plus whatever that record spends | The recursive cost is invisible in your own record |
| `exists:` | 1 | Rare outside macro-based setups |
| `ptr` | 1, and deprecated | Slow and unreliable; remove it |
| `redirect=` | 1, and replaces the rest | Only takes effect if no mechanism matched |

> **Careful** The limit is exceeded by *addition*, usually by somebody adding a marketing tool's `include` without checking. Nothing about the domain changes visibly; mail from every authorised host starts failing authentication at once, and the culprit is a record that looks perfectly reasonable.

## What SPF cannot prove

- **It does not authenticate the visible sender.** SPF checks the envelope sender. A message can pass SPF for `bounces.attacker.example` while displaying `From: Acme Traders` — which is why DMARC requires alignment between the authenticated domain and the header.
- **It breaks on forwarding.** A forwarder relays the message from its own address without changing the envelope sender, so the check fails at the final destination through no fault of anyone. SRS rewriting exists to address this and is not universal.
- **It says nothing about content.** An authorised host sending unpleasant mail passes.
- **It does not survive a mailing list.** Lists commonly rewrite the envelope, and some rewrite the header too, precisely because of the two points above.
- **A pass is not a reputation.** Authentication and trust are different questions; SPF answers the first only.

This is the reason the three-record set exists. SPF authorises the route, [DKIM](/docs/technology/dkim/) signs the message so it survives being relayed, and [DMARC](/docs/technology/dmarc/) requires that one of them aligns with the domain the reader actually sees.

## Does Connect use SPF, and who configures it?

**Educational, and a customer responsibility.** SPF, DKIM and DMARC are records published in DNS for the domain that mail is sent from. That domain belongs to the business, not to Connect, so **Connect does not set them and cannot set them for you.** Anyone telling you a mail tool has configured your SPF has described something that is not possible without control of your DNS.

What Connect does is send through the mailbox you connected — Gmail, Microsoft Graph, or your own SMTP server. The sending infrastructure is therefore your existing provider's, and the SPF record you already publish for that provider is the one that applies. Connecting a mailbox to Connect does not introduce a new sending host and does not require a new `include`.

The practical consequence is a short checklist for the business rather than for Connect: confirm the domain publishes exactly one SPF record, confirm it authorises the provider your mailbox actually uses, confirm the lookup count is under ten, and confirm it ends in `-all` once you are confident the list is complete.

## Questions

### Can a domain publish two SPF records?

No. More than one `v=spf1` TXT record on the same name is a permanent error, and receivers do not merge them — the policy is treated as broken. When two tools each want to be authorised, the mechanisms go into one record.

### Why does mail fail SPF only after being forwarded?

Because the forwarder relays from its own address while leaving the envelope sender as yours, so the final receiver checks an address your record does not authorise. Nothing is misconfigured; the protocol simply does not survive a relay. DKIM does, which is why the pair is stronger than either.

### Does Connect need to be added to our SPF record?

Not for mail sent through a mailbox you connected, because that mail leaves through your existing provider's infrastructure and your record already covers it. If your provider's own documentation asks for a particular `include`, that is the record to follow — it is a fact about your mail provider, not about Connect.

## Related

- [DKIM](https://connectbyjbrh.com/docs/technology/dkim/)
- [DMARC](https://connectbyjbrh.com/docs/technology/dmarc/)
- [SMTP](https://connectbyjbrh.com/docs/technology/smtp/)
- [Email deliverability](https://connectbyjbrh.com/docs/technology/deliverability/)
- [DNS](https://connectbyjbrh.com/docs/technology/dns/)
- [Email in Connect](https://connectbyjbrh.com/docs/email/)

## What this page is based on

- RFC 7208 — Sender Policy Framework version 1, https://www.rfc-editor.org/rfc/rfc7208
- RFC 5321 — the envelope sender that SPF evaluates, https://www.rfc-editor.org/rfc/rfc5321
- Connect channel source pack — docs-source/sources/CHANNELS.md §1, mail leaves through the workspace's own Gmail, Graph or SMTP mailbox
- Connect capability registry (docs-source/facts.py) — imap_smtp, gmail_oauth; no DNS-record capability is registered
