DMARCmetric

SPF record syntax explained

Updated 2026-08-05 · DMARC Fundamentals

An SPF record is one TXT record, on one line, that answers one question: which servers may send email using this domain in the envelope-from address? The syntax is small — a version tag, a handful of mechanisms, an optional qualifier on each — but it is unforgiving. A record with a typo does not warn you; it either fails open, fails closed, or is ignored entirely, and you find out from a DMARC report weeks later.

This page is the reference. If you want the concept first, read What is SPF?.

The shape of a record

v=spf1 ip4:198.51.100.7 include:_spf.google.com ~all

Three parts, always in this order. The middle part is where SPF mechanisms and SPF qualifiers live:

PartExampleRule
Versionv=spf1Must be first, must be exactly this
Mechanismsip4:… include:… mxEvaluated strictly left to right
The all mechanism~all / -allMust be last; everything after it is dead code

Evaluation stops at the first mechanism that matches. That is the single most important sentence on this page: order is not cosmetic. A record that begins with +all authorises the entire internet and never reaches anything you wrote after it.

Qualifiers: the character in front

Every mechanism can carry a qualifier. Omit it and you get +.

QualifierNameResult when the mechanism matches
+PassAuthorised (the default)
~SoftFailNot authorised, but accept and mark
-FailNot authorised, reject
?NeutralNo statement — treated like no SPF at all

In practice the qualifier only ever varies on all, because that is the catch-all for "none of my mechanisms matched". Which of ~all and -all you should publish is its own decision, covered in SPF softfail vs hardfail.

?all deserves a warning. It is not a cautious middle ground — it explicitly says "I make no claim", which is the same information a receiver has when you publish nothing at all. If you meant to be careful, ~all is the careful option.

The mechanisms

ip4 and ip6

The literal cases: a single address or a CIDR range.

ip4:198.51.100.7
ip4:198.51.100.0/24
ip6:2001:db8::/32

These cost no DNS lookups, which matters more than it sounds — see the ten-lookup limit below.

include

Hands evaluation to another domain's SPF record and asks: would that record pass this IP?

include:_spf.google.com

Two things surprise people. First, include is not a text merge — the other record is evaluated as its own question, and only a pass counts as a match. A SoftFail inside an included record does not softfail your message; it simply doesn't match, and evaluation continues. Second, its all mechanism is never applied to your record. Only the outcome of the mechanisms before it matters.

a and mx

Authorise the domain's own A/AAAA records, or the hosts named by its MX records.

a
mx
a:mail.example.com
mx:example.com

Bare a and mx mean "the current domain". Each counts as one term against the ten-term limit — but mx also triggers an address lookup per host it names, and RFC 7208 caps those at ten for a single mx.

exists

The SPF exists mechanism matches if a domain name resolves to anything at all. It is the escape hatch for macro-driven, per-sender logic and is rare outside large mail platforms. If you are hand-writing a record, you do not need it.

redirect — a modifier, not a mechanism

The SPF redirect modifier is the one entry that is not a mechanism at all.

v=spf1 redirect=_spf.example.com

Replaces your record with another domain's, wholesale — including its all. Unlike include, it is only consulted if no mechanism matched, and it is the last word: whatever the target says is your answer. Use it when several domains genuinely share one policy. Never combine it with an all mechanism, because all always matches and redirect will never be reached.

ptr — do not use it

The SPF ptr mechanism asks the receiver to do a reverse DNS lookup and check the result. RFC 7208 deprecates it in plain language: it is slow, unreliable, and imposes cost on the receiver. Some receivers ignore it outright. If you inherited a record containing ptr, replacing it is an improvement, not a risk.

The ten-lookup limit

SPF allows a maximum of ten DNS-querying mechanisms per evaluation. include, a, mx, ptr, exists and redirect all count; ip4, ip6 and all do not. Every include you add also drags in whatever that record looks up, recursively.

Exceed ten and the result is PermError — which most receivers treat as no SPF at all, so a record that looks generous fails everywhere at once. This is common enough to have its own page: Too many DNS lookups.

Syntax mistakes that break a record silently

MistakeWhat actually happens
Two SPF records on one domainPermError — receivers must not pick one. See multiple SPF records
v=spf1 not firstThe record is not an SPF record and is ignored
Anything after allUnreachable — all always matches
include:example.com/24include takes a domain, never a CIDR
ip4:example.comip4 takes an address, never a name
Splitting a long record into two TXT recordsTwo records = PermError. Long records must be split into multiple strings inside one record
A trailing +all "just in case"Authorises every host on the internet

One SPF record protects one thing: the envelope-from domain. It says nothing about the From address your recipient actually sees, which is why SPF alone cannot stop spoofing and why DMARC exists. That relationship is laid out in SPF, DKIM and DMARC: how they fit together.

A worked example

A company sends from Google Workspace, a marketing platform, and one legacy server on a fixed IP:

v=spf1 ip4:198.51.100.7 include:_spf.google.com include:sendgrid.net ~all

Read it aloud: version one; the legacy server passes; anything Google authorises passes; anything SendGrid authorises passes; everything else is a softfail. Lookup cost: zero for the ip4, plus whatever the two includes consume — comfortably inside the limit today, and worth re-checking each time a sender is added.

Once a record is in place, the reports tell you whether it matches reality. Sending sources, grouped by provider shows which senders are actually using your domain — including the ones nobody remembered to add.

Still stuck?

We answer every message — usually within one business day.

Email [email protected]