What this checks
A receiving mail server does not read your SPF record the way a person does. It takes the connecting IP address and the envelope sender domain, walks the record left to right, and stops at the first mechanism that matches. This page does exactly that and shows every step, so you can see which mechanism decided the outcome rather than guessing from a pass or fail.
Give it the sending IP address and a sender. A bare domain works; it becomes
postmaster@ that domain, which is what a bounce would use. The
result URL is shareable, so it can go straight into a ticket.
Reading the result
SPF has seven possible outcomes, and only two of them mean what people usually assume.
- pass: the IP is authorised. This is the only result that lets SPF satisfy DMARC.
- fail: the record ends in
-alland the IP matched nothing. The domain owner is saying to reject it. - softfail: the record ends in
~all. Not authorised, but the owner is not asking for rejection. Most receivers accept and mark it. - neutral: the record explicitly declines to say, usually
?all. Treated much like no record at all. - none: there is no SPF record, or the domain does not exist. SPF cannot contribute anything.
- permerror: the record could not be evaluated. Over the ten lookup limit, a syntax error, two SPF records, or more than two void lookups. See fixing PermError.
- temperror: a DNS lookup failed temporarily. Retry before concluding anything.
A pass is not the same as DMARC alignment
SPF authenticates the envelope sender, the address in MAIL FROM,
which recipients never see. DMARC additionally requires that domain to align
with the visible From: header. Mail relayed through a bulk sender
often passes SPF for the vendor's own bounce domain while failing DMARC, because
the two domains do not match. If your aggregate reports show SPF passing but
DMARC failing, alignment is where to look, not the record.
Why forwarded mail fails here
A forwarding server is not in the original domain's record, so on the second hop SPF fails legitimately. Nothing is broken; this is a known limitation of the protocol. It is also the clearest argument for configuring DKIM, which survives forwarding, so DMARC has a second way to pass.
Things worth testing
- A new sending platform, before you announce the change.
- An IPv6 sender, if your record only publishes
ip4mechanisms. Those messages fail and it is easy to miss. - A subdomain, which is evaluated against its own record and not the parent's.
- The same IP before and after a record change, to confirm you did not remove something that was authorising real mail.
To see where a record's lookups are going rather than testing one server, use the include tree. To generate a replacement record, check the domain on the home page.