Blog · Spf
Why a Mail Security Gateway Says No SPF Record on Legitimate Emails That Have Valid SPF
A sysadmin opens a Barracuda, Proofpoint, or Mimecast queue and sees legitimate mail from a Fortune 500 partner being blocked as "No SPF Record". The partner's IT team insists their SPF record is fine. Barracuda support blames the sender. Cyber-insurance forbids turning SPF checking off. Other messages from the same partner, minutes apart, sail through. The natural reaction is to assume someone is wrong. The reality: the SEG looked at a different domain than the one the user reads in Outlook.
SPF checks the envelope-from domain, not the From domain
Every SMTP transaction carries two "from" addresses. The first is the MAIL FROM (also called the envelope sender or Return-Path). This is what SPF actually checks, per RFC 7208. The second is the From: header that the user reads in their inbox. The visible From is for humans. The MAIL FROM is what the SEG queries.
Large senders almost never send from the same domain the user sees. The visible From might be partner.com, but the MAIL FROM is something like bounce.partner.com or a bounce-handling subdomain belonging to the partner's marketing platform. That bounce domain is a separate DNS zone, and it has to publish its own SPF record. When it does not, the SEG correctly reports "no SPF record" for that domain. Pull the original message and read the Return-Path: header. Whatever domain appears there is the one the SEG queried.
The first diagnostic: identify the actual envelope-from domain
Before opening a ticket, copy the Return-Path domain from a blocked message and run a single dig command:
dig TXT envelope-from-domain
If no record returns, the partner's bounce sub-domain genuinely has no SPF. If a record does return, the second diagnostic kicks in. Common shapes the reader will see:
- bounce.partner.com - the partner's own bounce handling
- em.foo.partnermail.net - a third-party marketing platform's bounce domain
- a long subdomain belonging to an ESP such as Mailchimp or SendGrid
The user looking at partner.com in their inbox has been assuming the SEG queried partner.com. It did not.
The second diagnostic: the SPF record itself
Once the actual SPF record is in hand, the next question is whether it can be evaluated at all. SPF has a hard limit: the 10-DNS-lookup ceiling defined in RFC 7208 section 4.6.4. Every mechanism that triggers a DNS query - a, mx, ptr, include, exists, redirect - counts. Once the receiver exceeds ten, the result is PermError.
Most modern SEGs handle PermError correctly and show "SPF PermError". Some do not. Some collapse PermError into a generic "No SPF Record" in the admin UI, which is the misleading wording the user is seeing. The fastest way to test: use spfquery from libspf2, or any online SPF checker that reports the lookup count. If the record crosses ten, the partner has to flatten it (replace nested include chains with direct ip4/ip6 entries) or break it into separate records. The user cannot do that for the partner. They can prove the problem, hand over a one-line answer, and move on.
When the message has been forwarded or passed through a mailing list
A separate root cause is the forwarder. If the partner's email passed through a forwarding service or a mailing list on the way to the SEG, the new sender is the forwarder. The SEG now queries the forwarder's envelope-from domain. If the forwarder does not publish its own SPF, every message that goes through it looks like "no SPF". ARC (Authenticated Received Chain, RFC 8617) is the modern answer: a SEG that honours ARC can recognise a previously authenticated message and let it through even when the forwarder has no SPF. Not every SEG honours ARC. The practical workaround is to ask the partner whether the affected traffic is going through a specific forwarder, and either add the forwarder to the partner's SPF include or stop using it.
How to read the SEG's own log
The SEG's log line for a blocked message shows one of five result codes, and they are not interchangeable:
- none - the SEG queried the envelope-from domain and there was no SPF record at all
- neutral - there was a record but it explicitly said +? (the owner opted out of the check)
- fail or softfail - the record was evaluated and the sender's IP did not match
- permerror - the record existed but could not be evaluated, most often the 10-lookup limit
- temperror - a transient DNS failure during the check
The instinct will be to read "No SPF Record" as "none". It might be. It might also be "permerror" misclassified. Knowing which one is the difference between asking the partner to publish a new record and asking them to flatten an existing one. The SEG's log tells the truth even when the admin UI does not.
A practical way to talk to the partner's IT team
Once the user knows which envelope-from domain the SEG queried and which result code it logged, the conversation with the partner is short. The framing is debugging, not blame:
- "The blocked messages have envelope-from bounce.partner.com. Can you confirm what SPF record resolves for that subdomain?"
- "When you query that record, how many DNS lookups does it trigger? RFC 7208 caps the count at ten."
- "We see the same partner successfully delivering under their visible From domain. Can you check whether a different bounce sub-domain is sending the messages that fail?"
The partner's IT team will recognise this as the kind of question that means the user has already done the work. The fix is targeted.
A cross-side check using DMARC aggregate reports
The strongest cross-side check is the partner's own DMARC aggregate reports. If the partner has published a DMARC record with a rua tag, the receiving mailboxes around the world are already sending back daily XML reports describing what they see. Those reports say, in plain text, which sending sources passed SPF, which passed DKIM, and which aligned with the visible From.
DMARCFlow is the practical way to use those reports. It takes the aggregate reports from a domain's rua endpoint and shows the partner, in plain English, which of their sending sources pass or fail SPF and DKIM alignment today. The receiver gets a one-line answer in either direction - "your published records are correct, the SEG is wrong" or "your bounce sub-domain is missing an SPF include, here is the report".
FAQ
Is "No SPF Record" always a sender misconfiguration?
No. It can also be a PermError being misclassified by the SEG, or a forwarder that does not publish its own SPF. The envelope-from domain is what the SEG actually queried, and that is where the fix starts.
Why does my SEG say no SPF when MXToolbox shows the record exists?
MXToolbox usually shows the record for the visible From domain. The SEG may have queried a different domain - the envelope-from. Check the Return-Path header in the original message to see which one.
How do I tell whether my SEG is doing HELO-only SPF or MAIL FROM SPF?
Look at the SEG log line for the blocked message. The query it performed is logged. Most modern SEGs do MAIL FROM, but some fall back to HELO when MAIL FROM is empty. The log tells you which.
What is the difference between none, neutral, and permerror in the SEG log?
None means no SPF record existed for the queried domain. Neutral means the record explicitly opted out. Permerror means the record existed but could not be evaluated - the most common reason is the 10-DNS-lookup limit.
Can a SEG disable SPF checks per-sender while keeping it on globally?
Most enterprise SEGs allow a per-sender exception list. Cyber-insurance policies sometimes permit this for known partners, and the audit trail is usually more important than the technical default.
Closing thought
A SEG reporting "No SPF Record" on legitimate mail almost never means the sender forgot to publish SPF. It means the SEG looked at a domain other than the one the receiver assumed. Identify the envelope-from domain, check whether it publishes SPF, and read the SEG log for the result code. Those three things, and the partner conversation is short.