exp: SPF Modifier
The SPF exp modifier lets you provide a custom human-readable explanation when SPF fails. Learn how to set it up and where it appears.
Published · Last verified · Maintained by TamingDNS
Modifier
exp=<domain>
Yes (counts toward 10-lookup limit)
exp=explain.example.com
💬 What This Modifier Does
The exp modifier lets you specify a domain whose TXT record contains a human-readable explanation of why SPF failed. This message may be included in NDR bounce messages returned to senders whose mail was rejected. It's used to provide helpful guidance, such as a link to your postmaster page or instructions for legitimate senders.
When to Use This
- Providing a helpful bounce message explaining why email was rejected
- Pointing senders to a postmaster page for delisting or contact
⚠️ Watch Out For
- Counts as one DNS lookup when an SPF failure occurs.
- Not all receiving MTAs surface the explanation in bounce messages.
- The explanation string supports SPF macros (%{d}, %{i}, etc.).
📋 Complete Example Records
Every one of these is a complete record you can paste as it stands. Try one in the SPF Checker or build your own with the SPF Builder.
v=spf1 mx -all exp=explain._spf.%{d}
RFC 7208 §6.2 uses this record. The %{d} expands to the domain being checked, so one record serves every domain you publish it on.
explain._spf.example.com. TXT "%{i} is not one of %{d}'s designated mail servers."
This is the TXT record the exp modifier points at. %{i} expands to the IP that was rejected, so the bounce names the address that failed.
explain._spf.example.com. TXT "See http://%{d}/why.html?s=%{S}&i=%{I}"
Also from §6.2. The URL carries the sender and IP, so a page can hand back specific instructions rather than a generic error.
v=spf1 mx ~all exp=explain._spf.%{d}
The explanation is only computed on a fail, and "~all" produces a softfail, so nobody ever sees this one.
📚 RFC References
🔗 Related SPF Elements
🔧 Related Tools
Check whether your current SPF record is valid and covers all your senders, or move on to the DKIM and DMARC side of the same job.