Skip to content

Blog

Notes on email hosting, domains and running your own mail.

Back to all articles

What Causes SPF Failures? A Practical DNS Guide

A message can leave your own mailbox, pass every test you can see, and still arrive with an SPF failure. That is frustrating, but it is usually not mysterious. When people ask what causes SPF failures, the answer is rarely “bad email.” It is usually an outdated DNS record, an unlisted sender, too many DNS lookups, or a forwarding setup that changed the message’s path.

SPF, or Sender Policy Framework, is a DNS policy that says which servers may send mail using a domain in the SMTP envelope sender, also called the Return-Path or MAIL FROM address. Receiving servers compare the IP address that delivered the message against that policy. If the IP is not authorized, SPF fails.

That narrow definition matters. SPF does not validate the visible From address by itself, and it does not measure whether a message is wanted. It answers one question: was this server allowed to send for this envelope domain?

What causes SPF failures in real mail systems

The most common cause is simple: a service is sending mail for your domain, but its sending infrastructure is not in your SPF record. This happens after switching transactional email providers, adding a help desk, connecting a website contact form, or enabling an accounting platform that sends invoices from your address.

A domain can have perfectly working person-to-person email and still fail SPF for password resets, order confirmations, calendar notices, or support replies. Each system may use a different envelope sender. Check the Return-Path in the message headers rather than assuming the visible From address tells the full story.

A sender was added but DNS was not updated

Suppose `example.com` sends regular mail through one host but sends website forms through another. If the SPF record authorizes only the first host, mail from the form service will fail SPF.

The fix is to add the provider’s documented SPF authorization to the existing record, usually with an `include:` mechanism. Do not create a second SPF TXT record. SPF expects one policy record per domain. Multiple SPF records can produce a permanent error, often shown as `permerror`, instead of a useful pass or fail result.

This is also why copying and pasting an entire SPF record from a vendor’s setup page is risky. It may overwrite your existing authorizations. Add the required mechanism to the record you already have, then test the published result.

The SPF record has too many DNS lookups

SPF has a hard limit of 10 DNS lookups during evaluation. Includes, redirects, `a`, `mx`, `exists`, and `ptr` mechanisms can consume that budget. A record may look short while the providers it includes point to more records underneath.

This is a common problem for organizations that accumulate tools over time: a marketing platform, a CRM, a help desk, a billing service, a form service, and two former providers nobody removed. One record ends up authorizing an entire history of software decisions.

When the lookup limit is exceeded, receivers generally return `permerror`. Some systems treat that harshly, and others may handle it inconsistently. Either way, it is not a record to leave in place.

The practical fix is subtraction. Remove services that no longer send mail for the domain. If several tools use the same provider, confirm whether one include already covers them. Avoid `ptr`, which is discouraged and can create unnecessary lookups. SPF flattening can reduce lookup count, but it creates maintenance work because provider IP ranges change. It is reasonable for a stable, closely managed setup, not a set-it-and-forget-it shortcut.

The record has a syntax or publishing error

SPF syntax is unforgiving enough to cause trouble and flexible enough to hide it. Common errors include missing spaces between mechanisms, an invalid IP range, a typo in an include domain, or putting the policy on the wrong hostname.

A basic record might look like this:

`v=spf1 include:sender.example.net -all`

The `v=spf1` tag must come first. Mechanisms are separated by spaces. The ending matters too. `-all` means mail from anything not listed should fail. `~all` is a soft fail, which tells receivers the sender is probably unauthorized but gives them more discretion. `?all` is neutral and offers little protection.

For an established domain with known sending sources, `-all` is usually the honest policy. Using `~all` forever does not fix an incomplete record. It just makes the policy less decisive while you postpone the inventory work.

Publishing can fail in less obvious ways. DNS control panels sometimes split long TXT values into quoted segments. That is normal when done correctly. What is not normal is adding extra spaces, stray quotation marks, or a second record that starts with `v=spf1`. DNS propagation can also make a correct change appear broken for a while, especially if a previous record had a long TTL.

Forwarding breaks SPF by design

Forwarding is one of the most misunderstood causes of SPF failures. A forwarder receives a message from an outside sender and then relays it to another mailbox. Unless the forwarder rewrites the envelope sender or uses Sender Rewriting Scheme (SRS), the receiving server sees the forwarder’s IP address sending on behalf of the original sender’s domain.

That forwarder is usually not authorized in the original sender’s SPF record, so SPF fails. The original sender did nothing wrong. The forwarder changed the route.

This is why SPF alone is not enough for modern email authentication. DKIM can survive forwarding if the message is not modified, and DMARC can pass through aligned DKIM even when SPF fails. A properly configured forwarder should support SRS, but delivery still depends on the full authentication chain and how the message is handled along the way.

If you operate aliases or forwarding rules, test them with messages from major providers and from your own domain. Do not judge the setup only by whether the message arrives. Inspect the authentication results in the final mailbox.

The wrong domain is being checked

SPF checks the envelope sender domain, not necessarily the domain people see in the From field. A message may display `billing@yourdomain.com` while using a return path like `bounce.vendor-mail.net`. In that case, SPF evaluates the vendor domain. That can pass SPF without helping DMARC alignment for `yourdomain.com`.

The reverse also happens: a vendor may use your domain in the return path, making your SPF record responsible for authorizing its IPs. The headers reveal which arrangement you have.

For DMARC, SPF only counts when the authenticated envelope domain aligns with the visible From domain under your alignment policy. This is why “SPF passed” is not always the same as “DMARC passed.” Treat them as connected but separate checks.

A practical way to diagnose an SPF failure

Start with one failed message, not the DNS record. Open its full headers and find the `Authentication-Results` line. It should show the SPF result, the domain evaluated, and often the client IP. Then compare that IP and domain with the SPF record actually published for that domain.

Ask three plain questions: Which system sent this message? Which envelope domain did it use? Does that domain’s record authorize this sender without exceeding the lookup limit? Those questions resolve most cases faster than changing qualifiers at random.

If the result is `fail`, the sender is probably unauthorized. If it is `permerror`, look for multiple records, invalid syntax, or more than 10 lookups. If it is `temperror`, the receiver may have encountered a temporary DNS failure. Retest before making a permanent DNS change.

Keep a small sender inventory as part of domain administration. Include your mailbox host, website, transactional provider, support system, and any platform allowed to send as your domain. Remove a sender when you remove the service. This is boring infrastructure work, which is exactly why it prevents expensive surprises.

FranklyMail’s DNS verification can help confirm that an SPF record is present and syntactically usable, but no verifier can know about a forgotten website plugin or a vendor configured six months ago. The domain owner still needs to decide who is allowed to send.

A clean SPF policy is less about clever syntax than accurate ownership. Know every system that sends mail, authorize only those systems, and test the routes that change along the way.