CertaDNS
Skip to lesson

Diagnosing in the Wild · lesson 4 of 4

Results that look impossible

After this lesson you can

Explain a pass that was rejected, and a fail from a host you know is authorised.

Assumes you have read Tracing a permerror to its term.

Four reports that sound like the protocol is broken. Each has a mundane explanation, and recognising them saves a day of looking in the wrong place.

"SPF passed but the mail was rejected"

Almost always DMARC alignment. SPF passed for the envelope domain, which was a vendor’s; the From header was yours; nothing aligned, and the DMARC policy applied.

Authentication-Results:
  spf=pass smtp.mailfrom=bounce.vendor.example     <- passed, for the vendor
  dmarc=fail header.from=acme.com                  <- rejected, for you

The tell is two different domains on those two lines. SPF did its job perfectly; it was simply never asked about the address the recipient saw.

Less commonly: the receiver rejected for content or reputation, and SPF is irrelevant to the rejection entirely. Read the SMTP response rather than assuming.

"It failed from a host that is definitely in our record"

CauseCheck
Evaluation never reached that termAn earlier all, or a match above it.
The record is at permerrorThen nothing passes, including listed hosts. Audit it.
The envelope domain is a subdomainSPF is not inherited. mail.acme.com needs its own record.
The host sent over IPv6The record lists ip4 only. Very common and looks random.
A stale cached recordQuery the authoritative server directly.

The IPv6 one catches everybody once

A host with both A and AAAA records will happily connect over IPv6 to a receiver that offers it. If your record has no ip6 term, that connection fails SPF while the same host passes over IPv4 — so it fails for some recipients and not others, with no pattern anyone can see from the sending side.

"It works for Gmail but not Outlook"

  • Different resolvers, different caches. One may hold a record you have since fixed.
  • Different transport. See above — one receiver offers IPv6, the other does not.
  • Receivers apply their own policy on top of the SPF result. The result can be identical and the disposition different.

"Nothing changed and it broke"

Nothing you changed. Records go over the lookup budget on their own when a platform restructures its own record, and an include target that gets decommissioned turns into void lookups without anyone editing anything. This is module 8, and it is the most common explanation for a record that was fine for a year and is not today.

Knowledge check

A host listed explicitly in your SPF record fails for some recipients and passes for others. The record is valid and well under the lookup limit. What is the most likely cause?

Try it on a real domain

Free, no account, public DNS only.

Go deeper

Last reviewed