Glossary · SPF

SPF

A DNS TXT record naming the servers allowed to send mail for a domain. On its own it is weak, so pair it with DKIM and DMARC.

Definition

SPF lists the servers allowed to send email for a domain. It is a DNS TXT record. SPF alone is not enough; pair it with DKIM and DMARC.

SPF lists the servers allowed to send email for a domain. It is a DNS TXT record. SPF alone is not enough; pair it with DKIM and DMARC.

All glossary terms
A wooden abacus with brass beads, three rows pushed to one side.

The short version

  • SPF, the Sender Policy Framework, is a DNS TXT record that lists which servers a domain authorises to send mail, and what a receiver should conclude when the sending server is not on the list.
  • It is evaluated against the envelope sender, the address in MAIL FROM, not against the From header a person sees. That single fact explains most confusion about SPF.
  • The record has a hard budget of ten DNS lookups per check, and include chains consume that budget quickly. A record that exceeds it returns permerror and authenticates nothing.
  • Void lookups are capped separately at two. A mechanism that queries a name with no answer can push a valid-looking record into permerror.
  • SPF alone does not authenticate the visible From domain. DKIM and DMARC alignment are what connect a passing check to the brand a recipient sees.
  • Publish one record per sending domain, start with a soft fail, watch DMARC reports, and only then move to a hard fail.

SPF, defined against the identity it checks

SPF is a published statement about sending infrastructure. A domain owner publishes a TXT record beginning v=spf1 that lists mechanisms: IP addresses, address blocks, other domains whose senders are authorised, and a final all mechanism with a qualifier. When a receiving server gets a message, it extracts the domain from the SMTP envelope sender, fetches that domain’s SPF record, evaluates the connecting IP against the mechanisms and produces a result: pass, fail, softfail, neutral, none, temperror or permerror.

The envelope sender is the address used in the MAIL FROM command, which usually appears to the recipient as the return path. It is not the From header rendered in the inbox. This is the most important distinction on the page. SPF answers whether the server that connected was allowed to send for the envelope domain. It says nothing, by itself, about whether the visible From domain authorised the message. That gap is what DMARC was designed to close.

Flow of an SPF check from SMTP connection through envelope sender extraction, DNS lookup, mechanism evaluation and a pass or fail result. 1 Connect 2 Read MAIL FROM 3 Fetch TXT record 4 Evaluate mechanisms 5 Return result
Figure 1. The check starts with the envelope sender. If you are looking at the From header to debug SPF, you are looking at the wrong identity.

What SPF is not: it is not encryption, it is not a spam filter, it is not a reputation system, and it is not a guarantee that a message is wanted. It is also not a property of the visible sender. A message can pass SPF for a bounce domain while displaying a forged From header, and a message can fail SPF after being legitimately forwarded while being entirely genuine.

What the receiver actually does

The receiving server has a connecting IP, a HELO or EHLO name, a MAIL FROM address and a message. SPF uses the MAIL FROM domain when it is present. When MAIL FROM is empty, which happens with some bounce messages, the check falls back to the HELO identity. The server then performs a DNS lookup for TXT records on that domain, finds the record that begins v=spf1, and walks the mechanisms from left to right until one matches.

The first match decides the result, qualified by the mechanism’s prefix. A plus sign means pass, a minus means fail, a tilde means softfail, a question mark means neutral. If no mechanism matches and the record ends with all, the qualifier on all applies. If there is no record, the result is none. A DNS timeout produces temperror, which is temporary. A malformed record, multiple records or an exceeded limit produces permerror, which is permanent for that check.

Anatomy of an SPF record showing the version, include mechanisms, IP mechanisms, the all mechanism and the qualifiers that can precede each. LoopNow runtime v=spf1 version include authorised domain ip4 / ip6 literal addresses all default qualifier
Figure 2. Read a record left to right. The first matching mechanism wins, so the order is part of the policy, not a formatting preference.

The result is written into the message headers, usually as an Authentication-Results field added by the receiver and sometimes as a Received-SPF field. That header is the ground truth when you debug. It names the identity that was checked, the result and often the client IP. A screenshot from a seed panel is useful, but the header is what tells you which domain was actually evaluated.

The ten-lookup limit and the include chain

SPF evaluation has a budget of ten DNS queries per check. Mechanisms that trigger a query include include, a, mx, ptr, exists and redirect. A literal ip4 or ip6 mechanism costs nothing. The budget is global across the evaluation: when an include pulls in another domain’s record, the mechanisms inside that record also consume queries. A record that looks short can therefore be expensive, because the domains it includes are themselves including other domains.

This is the single most common reason a working record stops working. A company adds a CRM, the CRM’s include pulls in three more domains, and the total crosses ten. The result is permerror, which receivers treat as no valid authorisation. Mail may still be delivered, but it fails authentication, and DMARC alignment will fail with it. The failure often appears months after the change, when a vendor updates its own record.

Bar chart of DNS lookups consumed by each part of a sample SPF record against the limit of ten. Google include 3 lookups CRM include 2 lookups ESP include 3 lookups Own a: record 1 lookups Headroom 1 lookups
Figure 3. Sample lookup budget. The includes look small at the top level; most of the cost is inside the domains they delegate to.

Headroom is the design goal. Keep the count at eight or below so that a vendor can add a nested include without breaking you. Audit the count quarterly and after every new sending tool. Flattening, which replaces includes with literal IPs, can reduce lookups, but it converts a live delegation into a snapshot that goes stale when the vendor changes ranges. Choose flattening deliberately, with a refresh process, rather than as a one-time fix.

The void lookup trap and the missing include

A void lookup is a DNS query that returns no usable answer, either because the name does not exist or because it exists without the requested record type. RFC 7208 caps void lookups at two per check. Exceed that and the result is permerror, even if the visible record looks reasonable. The cap exists because void lookups are expensive for resolvers and were being used to amplify load.

The trap is easy to fall into with mechanisms such as a, mx, ptr and exists, especially when a domain has been decommissioned but the mechanism remains. An include of a domain that publishes no SPF record is a different failure: the include cannot be evaluated, and the result is permerror. Both cases produce the same operational symptom, mail failing authentication, and both are invisible unless someone audits the record and its dependencies.

Decision diagram for an SPF permerror, branching to too many lookups, a void lookup, a missing include record or multiple SPF records. Why is SPF returning permerror? decision Over ten lookups Trim or flatten Over two voids Remove dead mechanisms Include has no record Fix or remove it
Figure 4. Permerror has four usual causes. Check the count, the void cap, the include targets and whether two records were published by mistake.

The defensive habit is to resolve every dependency yourself. For each include, fetch the target record and count its queries. For each a or mx mechanism, confirm the name has an address record. For each exists, confirm the macro expands to something that resolves. Do this before a campaign, not after a deliverability complaint, and record the date of the audit so the next person knows how stale the picture is.

Why SPF alone does not authenticate the From domain

SPF authenticates the envelope domain. The From header is a different field, and nothing in SPF requires the two to match. A sender can pass SPF for a domain it controls while displaying a completely different brand in the From header. That is not a bug in SPF; it is the scope of the protocol. The result is that a domain can have a perfect SPF record and still be impersonated in the field recipients actually see.

DMARC closes the gap with alignment. It requires that a passing SPF check use a domain aligned with the From domain, or that a passing DKIM signature use a d= domain aligned with it. Alignment can be strict, meaning an exact match, or relaxed, meaning the same organisational domain. This is why the standard advice is to publish SPF, DKIM and DMARC together: SPF authorises infrastructure, DKIM proves integrity and origin of signed content, and DMARC ties either one to the visible sender and tells receivers what to do on failure.

Comparison of SPF, DKIM and DMARC across what each authenticates, what it survives and what it does not cover. SPF DKIM and DMARC • Envelope domain• Authorises sending IPs• Breaks on forwarding• No content integrity• Ten lookup budget • Signed headers and body• Survives much forwarding• DMARC requires alignment• Policy on failure• Reporting built in
Figure 5. Three protocols, one chain of trust. SPF authorises the path, DKIM signs the content, DMARC aligns the result with the From domain.

Forwarding is the other reason SPF is fragile on its own. A mailing list or a forwarder often re-sends a message with a new envelope sender, so the SPF check is performed against the forwarder’s domain rather than the original author’s. SPF can fail even though the message is genuine. DKIM survives many forms of forwarding because it signs content rather than the path. A programme that relies on SPF alone will misclassify legitimate forwarded mail.

Publishing for a multi-vendor estate

A typical Indian company does not have one sender. It has Google Workspace or Zoho for staff mail, an email service provider for campaigns, a CRM or support tool that sends notifications, a transactional provider for receipts and OTP-adjacent mail, and possibly an agency sending on a subdomain. Each sender has its own infrastructure, and each one needs to be represented in the record or delegated to its own subdomain.

There are two clean patterns. The first is one record on the main domain that includes every authorised sender, with a lookup budget that fits. The second is subdomain delegation: marketing mail sends as mail.example.in or news.example.in, each subdomain publishes its own record, and the main domain stays small. The second pattern is usually easier to operate because a marketing vendor change does not consume the transactional domain’s budget, and a compromise on one subdomain does not automatically authorise the other.

Architecture of a sending estate with staff mail, campaigns, transactional mail and an agency, each authorised by a domain or subdomain record. Main domain Staff mail Transactional Support Marketing Campaign ESP CRM Agency Records SPF DKIM DMARC Monitoring Reports Alerts Audit
Figure 6. One domain or several, but every sending identity needs a record. Subdomain delegation keeps each vendor’s lookup budget separate.

Every sending subdomain needs its own record. SPF does not automatically inherit the organisational domain’s policy for a subdomain in the way DMARC policy discovery does. A subdomain with no record returns none, which is not a pass. If you add a subdomain for a new campaign tool, add the record in the same change window as the DNS entry, not after the first send.

Soft fail, hard fail and the rollout order

The all mechanism is the default. A record ending in ~all returns softfail for anything unmatched, which most receivers treat as suspicious but not necessarily rejectable. A record ending in -all returns fail, which is a stronger statement and can cause rejection. Starting with -all on a domain with unknown senders is how an OTP flow breaks on a Sunday. Start with ~all, publish DMARC at p=none, collect reports, identify every legitimate source, then move to quarantine and reject.

The rollout has a sequence. Inventory the senders by reading DMARC aggregate reports and mail logs, not by asking around. Publish SPF for each sending domain and confirm each sender appears in the reports as passing. Publish DKIM keys and confirm signatures validate. Move DMARC from none to quarantine with a small percentage, watch the failure reports, then to reject. Only after that tighten SPF from ~all to -all if the inventory is complete.

Timeline of an SPF and DMARC rollout from sender inventory through soft fail, monitoring, quarantine and hard fail. Week 1 Inventory senders logs and reports Week 2 Publish SPF and DKIM soft fail Week 3 DMARC p=none collect reports Week 6 Quarantine at low percent watch failures Week 10 Reject and tighten SPF full inventory
Figure 7. The safe order: inventory, publish, monitor, quarantine, reject, then tighten. Skipping the monitoring step is how legitimate mail gets blocked.

Change control matters because DNS is shared. One team adding a vendor record can alter the lookup count for everyone. Keep the record in a repository, review changes, and require the lookup count and the sender list in the pull request. A DNS change that is not reviewed is a production change without a review, whatever the interface looks like.

Flattening, macros and the maintenance trade-off

Flattening replaces include mechanisms with the IP addresses those includes resolve to. It reduces DNS lookups and can rescue a record that has run out of budget. It also freezes a live delegation into a snapshot. When the vendor adds a range, changes a provider or retires an IP, the flattened record is wrong, and the failure appears as authentication loss for a sender you thought was authorised. Automated flattening services refresh the snapshot, which introduces a dependency on that service and a new availability question.

Macros are the opposite trade: they make a record dynamic without extra includes. A macro can insert the sender’s domain, IP or a validated value into a mechanism, and exists can test a computed name. Macros are powerful and easy to get wrong. A malformed macro can produce a permerror, and a macro that expands to an attacker-controlled string is a security problem. Use them only when the simpler mechanisms cannot express the policy, and test the expansion explicitly.

Decision diagram for choosing between include delegation, subdomain delegation and IP flattening for an SPF record. Over the lookup budget? decision Many vendors Delegate a subdomain Stable IPs Flatten and refresh Few senders Trim unused includes
Figure 8. Three ways to stay under the limit. Subdomain delegation keeps the policy live; flattening buys headroom at the cost of a refresh process.

The honest position is that SPF is a small, static configuration that needs an owner. Whether you flatten or delegate, someone has to know the sender inventory and review it when a vendor changes. The record is not fire and forget; it is closer to a firewall rule that happens to live in DNS.

Worked example: four senders, one budget

A sample domain, example.in, sends through Google Workspace for staff mail, an ESP for campaigns, a CRM for notifications and a transactional provider for receipts. The record begins with v=spf1, includes the Google record, the ESP record, the CRM record and the transactional record, adds one literal IP for an in-house application, and ends with ~all during the rollout. The top-level record has four includes and one ip4, but the includes pull in nested records that also consume queries.

An audit resolves each dependency. Google’s include costs three queries in this example, the ESP costs two, the CRM costs two and the transactional provider costs one, plus one for the in-house a record. That is nine, leaving one query of headroom. A new vendor with a single include would fit; a vendor with a nested include chain would not. The team decides to move campaigns to a marketing subdomain with its own record, which brings the main domain down to six queries and gives each vendor room to change.

Grid of four sending sources with their SPF lookup cost and the subdomain decision for each. Google staff 3 lookups Campaign ESP 2 lookups CRM notices 2 lookups Receipts 1 lookup In-house app 1 literal Headroom 1 left
Figure 9. Sample sender inventory. The campaign source moves to its own subdomain, which is the decision that creates durable headroom.

The marketing subdomain is published with its own SPF, its own DKIM selector and its own DMARC policy. The main domain keeps the transactional and staff senders. Reports are separated, so a campaign reputation problem does not contaminate the receipts stream. The change is a DNS project, not a product project, and it takes an afternoon once the inventory is written down.

Testing and the mistakes that keep repeating

Test from the outside. Query the TXT record with a DNS tool, count the lookups with an SPF checker that follows includes, and send a message through each sender to a mailbox you control. Read the Authentication-Results header and confirm the identity that was checked, the result and the client IP. If the header says spf=pass with smtp.mailfrom equal to your envelope domain, the check worked for that path. Repeat per sender and per subdomain.

The recurring mistakes are well known and still common. Publishing two SPF records on one domain produces permerror. Using include for a domain that has no SPF record produces permerror. Letting the lookup count drift over ten produces permerror. Using ptr is slow, unreliable and discouraged. Forgetting a subdomain produces none. Starting at -all before inventorying senders blocks legitimate mail. Flattening without a refresh process creates a slow, silent failure. And expecting SPF to protect the From header without DMARC produces a false sense of security.

Wireframe of an authentication dashboard showing pass rates by sender, lookup counts and DMARC alignment status. Staff mail: pass Campaigns: pass Receipts: fail Lookups: 9 of 10 DMARC: align
Figure 10. A useful authentication view is per sender. The average hides the stream that is failing, and that stream is usually the one customers rely on.

Measure authentication per sender, not as one number. A dashboard that says ninety-eight percent SPF pass can hide a transactional stream at forty percent, and that stream is the one customers notice. Break the rate down by envelope domain, by sending IP and by receiving provider, and alert when a sender that normally passes drops. The alert is worth more than the average.

  • One SPF record per domain, never two.
  • Keep the lookup count at eight or below.
  • Audit void lookups and dead mechanisms.
  • Publish a record on every sending subdomain.
  • Pair SPF with DKIM and a DMARC policy.
  • Test from outside and read the Authentication-Results header.

Frequently asked questions

Does SPF check the From address?

No. SPF checks the envelope sender, the domain in MAIL FROM, and falls back to the HELO identity when MAIL FROM is empty. The From header a recipient sees is a different field. DMARC is what requires a passing SPF or DKIM result to align with that visible domain. This is why a domain can pass SPF and still be impersonated.

Why does our SPF record return permerror?

The usual causes are more than ten DNS lookups, more than two void lookups, an include pointing at a domain with no SPF record, or two SPF records published on the same name. A malformed mechanism or macro can also do it. Resolve each include yourself and count the queries, rather than trusting the top-level record length.

What is a void lookup?

A DNS query that returns no usable answer, either because the name does not exist or because it has no record of the requested type. RFC 7208 allows at most two per check. Mechanisms such as a, mx, ptr and exists can create them when a domain has been retired. Exceeding the cap produces permerror even if the rest of the record is valid.

Should we use ~all or -all?

Start with ~all while you inventory senders and collect DMARC reports. Move to -all only when every legitimate source is known to pass, including transactional streams and any agency or regional vendor. A hard fail on an incomplete inventory blocks real mail, and the failure often appears at the worst possible time, such as during a password reset flow.

Why did SPF break after we forwarded mail?

Forwarding often changes the envelope sender to the forwarder’s domain, so the SPF check is performed against the forwarder rather than the original author. The message can be genuine and still fail. DKIM is more resilient because it signs content, and DMARC alignment can still pass on a valid DKIM signature. Relying on SPF alone will always misclassify some forwarded mail.

Do subdomains inherit the main domain’s SPF record?

No. SPF evaluates the domain in the envelope sender. A subdomain with no record returns none, which is not a pass. If you send from mail.example.in or news.example.in, publish a record there. DMARC policy discovery can fall back to the organisational domain, but SPF authorisation does not. Treat every new sending host as a new record to publish.

Is flattening a good idea?

It is a reasonable way to stay under the lookup limit when your sending IPs are stable, provided you have a refresh process. It becomes a liability when a vendor changes ranges and nobody notices. Automated flattening services solve the refresh problem but add a dependency. Delegating a subdomain is often the cleaner answer.

How many SPF records should a domain have?

Exactly one. Multiple records produce permerror because the receiver cannot know which policy to apply. If you need to combine senders, merge the mechanisms into one record, respecting the lookup budget. If the record grows too large, split by subdomain rather than publishing a second record on the same name.

Does SPF stop phishing?

Only partly. It can stop a sender from using your envelope domain without authorisation, and with DMARC enforcement it can stop messages that display your From domain without a passing aligned authentication result. It does not stop lookalike domains, compromised accounts or convincing content. Treat it as one control in a wider programme, not as a shield.

Sources and further reading

  1. RFC 7208 — Sender Policy Framework
  2. RFC 5321 — Simple Mail Transfer Protocol
  3. RFC 7489 — DMARC
  4. RFC 6376 — DKIM signatures
  5. Google Workspace — SPF records
LoopNow AI Answers from published LoopNow pages
Hi — ask me about LoopNow products, pricing, DPDP or migration. I answer from the published site and can connect you to the team.
Contact page