# SPF (Sender Policy Framework): Definition and How It Works

Source: https://wraps.dev/glossary/spf

AuthenticationSender Policy FrameworkSPF record

An SPF record is a DNS TXT record that lists which servers are allowed to send mail for a domain, checked against the envelope return-path rather than the visible From address.

## What the record actually says

A domain publishes one TXT record starting with \`v=spf1\`, followed by a sequence of mechanisms (\`ip4\`, \`ip6\`, \`a\`, \`mx\`, \`include\`, \`redirect\`) and a trailing qualifier that says what to do with everything not explicitly listed. A receiving mail server resolves that record for the return-path domain on the incoming message and walks the mechanisms in order looking for a match. RFC 7208 permits exactly one SPF record per domain; a second one is not additive, it is invalid, and Wraps' own deliverability checker treats multiple records as a hard failure rather than trying to merge them.

## The 10-lookup limit is the part people miss

Every \`include\`, \`a\`, \`mx\`, \`ptr\`, \`exists\`, and \`redirect\` mechanism costs one DNS lookup, and RFC 7208 caps the total at 10 for the whole chain, including lookups inside nested includes. \`ip4\` and \`ip6\` mechanisms are free because they need no lookup. An SPF record that exceeds 10 lookups is specified to return \`permerror\` — the receiving server is required to treat it as broken, not to try harder. Wraps' email-check package walks this chain recursively and warns at the limit and warns again over it, but it doesn't currently fail the check for this the way a real receiving server would — a 15-lookup record still reports as valid today, which is a gap worth knowing about rather than trusting the tool to catch for you.

## The qualifier at the end decides enforcement

The final mechanism is almost always some form of \`all\`, and the character in front of it is the qualifier: \`+\` (pass, and never write this explicitly), \`-\` (hard fail), \`~\` (soft fail), or \`?\` (neutral). \`~all\` tells a receiver to accept-but-flag mail from an unlisted source; \`-all\` tells it to reject outright. For a sending domain, \`~all\` is the correct default: it gives you a way to add a forgotten sending source without an outage. \`-all\` is appropriate only once DMARC is enforcing (\`p=quarantine\` or \`p=reject\`), because at that point DMARC — not a bare SPF fail — is what determines the recipient's disposition, and a \`-all\` without an enforcing DMARC just adds a second way for a legitimate but unlisted source to bounce.

## SPF authenticates the return-path, not the From address

This is the single most common source of confusion about SPF. The check runs against the envelope sender (the MAIL FROM / return-path address), which a recipient never sees, not the visible From: header a human reads. A message can pass SPF cleanly while its visible From domain has no relationship to the domain that actually passed. DMARC alignment is the mechanism that ties the two back together — see the \`dmarc-alignment\` and \`return-path\` entries.

## Why it matters

SPF is the cheapest of the three authentication mechanisms to get wrong, because a record that looks plausible at a glance can silently exceed the lookup limit or end in the wrong qualifier for your DMARC posture. Both failure modes cause real mail to be rejected or marked as failing authentication, and neither shows up until a recipient's mail server actually evaluates the record.

## How to check it

```
dig +short TXT example.com | grep spf1
```

## Common questions

### Should my SPF record end in ~all or -all?

~all for almost every sending domain. -all is correct only once DMARC is enforcing (quarantine or reject), because at that point DMARC decides disposition and -all stops being the thing standing between a misconfiguration and a bounce.

### Why did adding one more include break my SPF record?

You likely crossed the 10-DNS-lookup limit RFC 7208 sets for the whole chain, including lookups nested inside other includes. Past that limit, SPF is specified to return permerror, which most receivers treat as a fail.

### Does SPF check the From address I see in my inbox?

No. SPF checks the envelope return-path, which is invisible to the recipient. Aligning that check to the visible From domain is what DMARC alignment does on top of SPF, not SPF itself.
