An SPF record is one TXT record in your domain's DNS that lists which servers may send mail for that domain. It begins with "v=spf1", names the authorized senders with mechanisms such as ip4, include and mx, and ends with an all mechanism. A domain may publish only one such record, and evaluating it may trigger no more than 10 DNS-querying terms. For publishers and shop owners who send newsletters, order emails or contact-form replies, the hard part is not the syntax. It is deciding which systems belong in the record and keeping the record inside its limits.
Collecting consent from subscribers is a separate subject; our piece on consent-based newsletter signups covers that side. What follows is the technical record itself: how each part reads, how records break, and how to check one after publishing.
What SPF checks
SPF is defined in RFC 7208 (Opens in a new tab). The domain owner publishes the list of hosts allowed to send for the domain, and a receiving server compares the connecting IP address against it and produces a result. Before the syntax, it helps to be clear about what the receiver looks at.
Which identity is checked
The RFC recommends that verifiers check the HELO identity separately (section 2.3) and requires them to check the MAIL FROM identity, the envelope sender, when no definitive HELO result exists (section 2.4). Neither is the From line a reader sees in a mail program. A pass therefore does not prove that the visible sender address is genuine. Linking SPF to the visible From domain is the job of DMARC alignment, which belongs to the DKIM and DMARC articles, not this one.
Where Google fits in
Google's email sender guidelines (Opens in a new tab) ask everyone who sends to personal Gmail accounts to set up SPF or DKIM for the sending domain, and ask senders of 5,000 or more messages per day to set up both. The page also tells you to publish an SPF record that includes all of your domain's email senders and warns that third-party senders you do not list are more likely to be marked as spam. It does not discuss the DNS lookup limit or syntax details; the RFC does. Google's thresholds and wording can change, so read the current page before relying on it.
The seven results
Section 2.6 of the RFC defines seven possible results. The table below reads them from a site owner's point of view.
| Result | Meaning | What it suggests to you |
|---|---|---|
| pass | The IP address is authorized | The record works for this sender |
| fail | Not authorized, stated explicitly | The sender is missing from the record or really is unauthorized |
| softfail | Not authorized, stated more softly | May be a transition setting, but still something to resolve |
| neutral | The record makes no assertion about this IP | The record may need to be extended |
| none | No SPF record found | The record is missing or published on the wrong name |
| temperror | A transient error, generally DNS | Try again later |
| permerror | A permanent error needing DNS operator action | The record is broken, over its limit, or duplicated |
The RFC describes temperror as a transient, generally DNS, error and permerror as one that definitely requires DNS operator intervention to be resolved (sections 2.6.6 and 2.6.7). A permerror is not a warning. It is a defect.
Reading the syntax
SPF records are published as TXT records. Section 3.1 of the RFC says use of the dedicated SPF record type has been discontinued. According to section 3, each SPF record sits at the owner name it pertains to, not in a subdomain below it. Mail whose envelope sender is at example.com is checked against the record at example.com.
Version, mechanisms and the default
The record starts with "v=spf1" (section 4.5). The mechanisms listed in section 4.6.1 are all, include, a, mx, ptr, ip4, ip6 and exists. Day to day, a site owner meets these:
| Mechanism | What it authorizes | Counts toward the 10 term limit |
|---|---|---|
| ip4, ip6 | A specific address or range | No |
| a | The A or AAAA addresses of a name (section 5.3) | Yes |
| mx | The addresses of the domain's MX hosts (section 5.4) | Yes |
| include | Whatever another domain's SPF record authorizes (section 5.2) | Yes |
| all | Matches everything, used as the default | No |
| ptr | Not to be used | Yes |
Section 5.5 puts "(do not use)" on the ptr mechanism and says it should not be published. A new record has no reason to include it.
Qualifiers: plus, minus, tilde, question mark
Each mechanism can carry a qualifier. "+" means pass, "-" fail, "~" softfail and "?" neutral. With no qualifier, "+" is assumed (section 4.6.2), so "mx" and "+mx" mean the same thing. A closing "-all" produces fail for anything not authorized earlier in the record, and "~all" produces softfail. Which one to choose is a judgment call. Practical suggestion: if you are not yet sure your sender inventory is complete, publish "~all", confirm that real mail passes, and tighten to "-all" later. The RFC defines what each qualifier produces; it does not give this advice.
Why all belongs at the end
Section 5.1 says all is meant to be the rightmost mechanism, and mechanisms after it must be ignored. A record written as "v=spf1 -all include:mailer.example" never reaches the include. A redirect modifier is also ignored when the record contains an all mechanism (sections 5.1 and 6.1).
Ranges, length limits and a sample record
Address ranges
For ip4 and ip6 the prefix length follows a slash: 0 to 32 for ip4 and 0 to 128 for ip6. Without a length, ip4 defaults to /32 and ip6 to /128. Partial addresses are not allowed; write "192.0.2.0/24", not "192.0.2." (section 5.6).
Long records: 255 and 512
One DNS character-string holds at most 255 octets. A longer record can be split into several strings, and the RFC says they are joined with no spaces added (section 3.3). Section 3.4 recommends keeping the record small enough that a query response fits within 512 octets. Whether your DNS panel splits long values automatically depends on the panel; if it rejects a long value, look for an option to enter it as several quoted strings.
A sample record, piece by piece
The record below is a placeholder; the domains and the address are example values.
v=spf1 ip4:198.51.100.25 include:_spf.mailer.example include:_spf.billing.example -all
| Piece | Reading |
|---|---|
| v=spf1 | An SPF version 1 record |
| ip4:198.51.100.25 | One fixed address, perhaps the web server |
| include:_spf.mailer.example | Authorize whatever the newsletter provider's record authorizes |
| include:_spf.billing.example | Authorize the invoicing tool the same way |
| -all | Everything else fails |
Six steps to a first record
- List every system that sends with your domain: newsletter, web server, helpdesk, invoicing, team mailboxes.
- Learn which domain each uses as its envelope sender. If a service uses its own domain there, your record is not the one evaluated for that stream.
- For systems that use your domain, note the include term or address range the provider documents.
- Combine the terms into one line starting with v=spf1, with all at the end.
- Count include, a and mx terms, nested ones included. The total must not pass 10.
- Publish it as a TXT record on the domain, replacing any existing SPF line rather than adding a second one.
A counting worksheet
Take this placeholder record: v=spf1 ip4:198.51.100.25 include:_spf.mailer.example mx -all.
| Term | Causes a query | Count |
|---|---|---|
| ip4:198.51.100.25 | No | 0 |
| include:_spf.mailer.example | Yes, plus its inner terms | 1 plus inner terms |
| mx | Yes | 1 |
| -all | No | 0 |
The total is 2 plus the include, a, mx, ptr, exists and redirect terms inside the referenced record. Query that record to find out. Providers can change their records without telling you, so repeat the count whenever a provider changes something and at regular intervals.
Multiple senders and include
A site can send mail from a newsletter provider, a web server, an invoicing tool and a helpdesk at the same time. All of them must be expressed in one record.
One record per name
Section 4.5 says that if the record set for a name contains more than one SPF record, the result is a permerror, and section 3.2 says a name must not have multiple records that would cause more than one to be selected. Provider instructions may tell you to "add this TXT record". Do not add it as a second line. Take the include term from their instructions and put it into the record you already have.
What include really does
Under section 5.2 only the evaluated result of the referenced record is used. A pass in the referenced record is a match. Fail, softfail and neutral are non-matches. Temperror and permerror are returned as errors, and a referenced name with no SPF record at all (none) produces a permerror. A "-all" inside the referenced record does not end the overall evaluation. In practice, a provider's own "-all" cannot shut out the other terms in your record.
redirect for owners of many domains
The redirect modifier hands evaluation to another domain's record when nothing else matched. If the target has no record or is malformed, the result is a permerror rather than none (section 6.1). It suits organizations that want one sender set for many domains; a single-site owner has little use for it.
Keeping a record tidy
- Write a note next to every term: which system, which owner, when added.
- Delete the term of any service you stopped using. A stale term keeps authorizing a sending path you no longer control.
- If a provider documents a fixed address range, an ip4 term saves lookups compared with an include, but the record goes stale if the provider changes the range. Use it only when the provider commits to the range.
A worked example: a regional news site
Example scenario: a regional news site
Example scenario: A regional news site sends its daily digest through a newsletter provider, its subscription invoices through an invoicing tool, and account notices from its own web server. The editor starts with the web server's fixed address as an ip4 term and adds the newsletter provider's include term. The invoicing tool sends with its own domain as the envelope sender, so the editor checks the tool's documentation before deciding whether the news site's record needs a term for it at all. Every term gets a note: system, owner, date added. When the invoicing tool is replaced a year later, nobody has to guess which term to remove.
The lookup limit and common errors
The most treacherous SPF fault is a record that looks correct yet exceeds a limit once it is evaluated.
What counts and what does not
Section 4.6.4 says include, a, mx, ptr and exists, plus the redirect modifier, cause DNS queries, and implementations must limit the total number of those terms to 10 during SPF evaluation. Above that, the result is a permerror. The all, ip4 and ip6 mechanisms cause no queries at evaluation time and are not subject to the limit. Terms inside referenced records are part of the same evaluation, so adding an include to your record also adds whatever that provider's record contains. A site that stacks a newsletter tool, a marketing automation tool and a helpdesk can reach the limit without ever writing ten terms itself.
MX hosts and void lookups
Each mx term counts toward the 10, and section 5.4 adds that a single MX record may trigger at most 10 address lookups; exceeding that also gives a permerror. Section 4.6.4 further says implementations should limit void lookups, queries that return nothing, to two. That is a SHOULD, but an include that points at a misspelled or deleted name can run into it.
Ways to stay under the limit
- Remove include terms for services you no longer use.
- Replace a and mx terms that resolve to a known fixed address with an ip4 term, remembering to update it if the address changes.
- Split streams across subdomains. Each name has its own record and its own limit.
- Ask providers for a fixed range or a leaner record if you are close to the limit.
Common errors
| Error | Result | Fix |
|---|---|---|
| Two separate SPF TXT records | permerror (section 4.5) | Merge terms into one record |
| all placed in the middle | Terms after it ignored (section 5.1) | Move all to the end |
| Stacking many includes | permerror past 10 terms | Count terms, delete unused ones |
| Using ptr | The RFC says it should not be published | Use ip4, ip6, a or include |
| Record on the wrong name | none result | Publish on the envelope sender's domain |
| Long record entered as one string | Panel rejects it or the value is broken | Split into strings of 255 octets or fewer |
| Include pointing at a deleted name | Void lookup, possible permerror | Review the inventory on a schedule |
Subdomains, silent domains and provider switches
Because each record belongs to the name it is published on, an SPF record at the parent domain is not automatically a record for a subdomain (RFC 7208 section 3). If the newsletter goes out from a subdomain, that subdomain needs its own record.
A subdomain per stream
Separating marketing mail and transactional mail onto different names gives each its own record and its own 10 term budget. Practical suggestion: a fault on one stream then stays on that stream. It is a design choice, not a requirement in either source.
Names that send nothing
A name that never sends mail can publish just "v=spf1 -all". No mechanism authorizes any address, so everything fails; this follows from the grammar, since the RFC does not make any single mechanism mandatory and all sets the default (section 5.1). Practical suggestion: parked or redirect-only domains are good candidates. How receivers react to a fail depends on their own policy.
Switching providers
- Add the new provider's include term to the existing record.
- Send test messages through the new provider and confirm the SPF result is pass.
- Stop sending through the old provider.
- Remove the old term last.
Reverse the order and mail from the new provider may produce fail or softfail during the transition. If both providers run side by side for a while, keep both terms and recount against the limit.
After publishing: checks and timing
Publishing is half the job. The record showing up in DNS, evaluating to a result and passing for real mail are three separate checks.
Three checks, in order
- Is there exactly one record, on the right name, as a TXT record? List the domain's TXT records with a DNS lookup tool and count the lines beginning with "v=spf1".
- Does it evaluate cleanly? An online SPF checker shows the lookup count and any permerror. Whichever tool you pick, read the 10 term limit and the single record rule against the RFC's numbers.
- Does real mail pass? Send a test message from each sending system to your own inbox and find the SPF result in the message headers. Header names and layout vary by mail service.
From result to cause
| Result you see | Look here first |
|---|---|
| none | Is the record on the envelope sender's domain, spelled correctly, as a TXT record? |
| fail | Is the sending IP covered by a term? The provider's range may have changed. |
| softfail | The record ends in ~all and the IP is not covered. |
| neutral | The record ends in ?all or makes no claim about this IP. |
| temperror | DNS may have failed briefly; retry shortly. |
| permerror | Duplicate records, the 10 term limit, broken syntax, or an include target with no record. |
If the connecting IP or the envelope domain in the header is not what you expect, the problem is not the record. A system you did not know about is sending as you, and the inventory has a gap.
Timing
How fast a DNS change spreads depends on your provider and the record's TTL. The official pages state no propagation time. The Google Workspace DMARC instructions ask for a 48 hour wait after setting up SPF or DKIM before adding DMARC, but that is not a propagation time for the SPF record. If a test run right after publishing shows the old result, wait a little and try again.
Checklist and decision rule
Post-publish checklist
- One v=spf1 record on the domain.
- The record ends with all, and no term follows it.
- The include, a and mx terms, nested ones included, total no more than 10.
- No ptr term.
- Test mail from the newsletter, web server and helpdesk shows SPF pass.
- Every term has a note naming its owner and reason.
Decision rule before adding a new service
- Does the service use your domain as the envelope sender, or its own? If its own, the SPF record may need no term for it; DKIM and alignment still need to be set up separately.
- Does the provider give an include term or an address range? For an include, recount your total.
- If the new term pushes you past 10, move the service to its own subdomain.
Practical suggestion: this rule is derived from the RFC and the Gmail page, which do not state it as a rule themselves.
SPF beside DKIM and DMARC
SPF is one of the two authentication methods the Gmail page names together; senders of 5,000 or more messages a day need both. If your newsletter carries paid placements, labeling matters too, as discussed in our note on sponsored content disclosure. Advertisers will ask for audience figures, which belong in a website media kit, and the clicks on newsletter links can be read more easily when links are tagged consistently, as in our post on sponsored-post reporting with UTM and Search Console.
Frequently Asked Questions
What type of DNS record is an SPF record?
Under RFC 7208 section 3.1, an SPF record is published as a TXT record; the dedicated SPF record type has been discontinued. It sits at the sending domain's own name and starts with v=spf1.
Can a domain have more than one SPF record?
No. Under RFC 7208 section 4.5, a record set with more than one SPF record produces a permerror. When you add a service, put its include term into the existing record instead of adding a second line.
What is the SPF 10 lookup limit?
RFC 7208 section 4.6.4 says include, a, mx, ptr and exists, plus the redirect modifier, cause DNS queries, and implementations must limit the total number of those terms to 10 during evaluation. Exceeding it produces a permerror. The all, ip4 and ip6 mechanisms are not counted.
What is the difference between ~all and -all?
The qualifiers are defined in RFC 7208 section 4.6.2: "-" produces fail and "~" produces softfail. What a receiver does with each result is up to its own policy. Practical suggestion: move to -all once you are sure the sender inventory is complete; that advice is not an official rule.
My SPF record is correct but mail goes to spam. Why?
SPF checks authorization for the envelope sender domain only. The Gmail page lists other factors such as DKIM, DMARC, alignment and the spam rate. A passing SPF result does not guarantee inbox placement.
How do I check an SPF record after publishing it?
Confirm that the domain has exactly one v=spf1 TXT record, use an online SPF checker to read the lookup count and any permerror, then send a test message from each sending system and read the SPF result in the headers.
Conclusion
An SPF record is a single TXT record: it begins with "v=spf1", lists authorized senders with mechanisms such as ip4, include and mx, and ends with "all". A domain may have only one record, evaluation may use no more than 10 DNS-querying terms, and ptr should not be used. After publishing, check the record count, the term count and the result on real messages separately. SPF covers the envelope sender, relates to the visible From domain only through DMARC alignment, and does not guarantee delivery.
If you want your newsletter audience to reach advertisers, you can browse guest post listings on Akua Adforce; scope and terms are written on each product page.
Post a comment
Please log in to leave a comment. Login