SPF flattening check
Follows the SPF include and redirect tree as a receiver counts it (10 DNS lookups, 2 void lookups, PermError stops the walk), resolves a and mx to addresses with any /cidr, and merges every block that gives pass, with its sources. exists, ptr and macros are listed apart. Analysis only: no flat record is suggested.
Updated 2026-10-28
What this tool checks
The SPF record and its include and redirect tree are read as the SPF check reads them, then evaluated in a receiver's order:
- ip4 and ip6 are taken as written; a and mx are looked up, with any
/cidrapplied (at most 10 MX names). - Only passing mechanisms count: a
-,~or?qualifier adds no block, and nothing afterallis reached. - Limits: the 11th DNS lookup, the third lookup without an answer or a syntax error in a record stops the walk, as at a receiver.
-aand-mxare looked up too, since they count, but add no block.
How to read the result
Each block is listed once, merged with overlapping and adjacent blocks, with up to five mechanisms it came from. The counts cover all blocks, also beyond the first 500.
Limitations
- At most 50 DNS queries are made per check; a larger tree is reported as incomplete.
- The result is a snapshot: providers change the addresses behind their includes.
Use it from code
API reference for SPF flattening check
curl -i "https://api.lookproof.dev/v1/mail/spf-flatten?domain=example.com"A request without payment is answered with 402 Payment Required and the exact price. See the API reference.
Limits
| Input | Domain |
|---|---|
| Deadline | 10 seconds |
| Freshness | Up to 5 minutes, never longer than the record TTL |
| Price | $0.01 per check |
Findings this tool can report
Check (1)
- Warning
CHECK_QUERY_BUDGET_EXCEEDEDThe check stopped after reaching its DNS query limit.
DNS (3)
- Error
DNS_DOMAIN_NOT_FOUNDThe DNS resolver reported that the domain does not exist. - Warning
DNS_RESOLVER_FAILUREThe DNS resolver returned a server failure. - Warning
DNS_RESOLVER_TIMEOUTThe DNS resolver did not answer in time.
SPF (15)
- Warning
SPF_FLATTEN_BROADThe SPF policy lets a very large address block pass. - Warning
SPF_FLATTEN_INCOMPLETEThe SPF policy could not be unfolded into a complete list of addresses. - Error
SPF_INCLUDE_LOOPThe SPF chain returns to a domain it already evaluated. - Error
SPF_INCLUDE_NOT_FOUNDAn included or redirected domain has no SPF record. - Info
SPF_MACRO_NOT_EVALUATEDAn SPF record contains macros that were not evaluated. - Error
SPF_MULTIPLE_RECORDSMore than one SPF record was found for a name in the SPF chain. - Warning
SPF_NEUTRAL_ALLThe SPF policy ends with ?all. - Warning
SPF_NOT_FOUNDNo SPF record was found for the domain. - Warning
SPF_NO_ALLThe SPF record has no all mechanism and no redirect. - Error
SPF_PASS_ALLThe SPF policy ends with +all. - Warning
SPF_PTR_MECHANISMAn SPF record uses the ptr mechanism. - Info
SPF_SOFTFAIL_ALLThe SPF policy ends with softfail (~all). - Error
SPF_SYNTAX_ERRORAn SPF record contains a term that cannot be parsed. - Error
SPF_TOO_MANY_LOOKUPSThe SPF record needs more than 10 DNS lookups. - Error
SPF_TOO_MANY_VOID_LOOKUPSMore than two SPF lookups returned no data.
Frequently asked questions
Does the tool write a flattened SPF record for me?
No. It shows which addresses the current policy lets pass. A flattened record copies providers' addresses into your own record, and it breaks without warning when a provider changes them, so the tool leaves that choice to you.
Why is the list incomplete?
Receivers stop after 10 DNS lookups or 2 lookups without an answer (PermError), and so does the tool. exists, ptr and macros depend on the sender and have no fixed addresses. SPF_FLATTEN_INCOMPLETE gives the reason.
Which blocks are too broad?
A merged block wider than /16 for IPv4 or /32 for IPv6 lets tens of thousands of addresses or more pass, often a shared provider network: SPF_FLATTEN_BROAD. A reachable +all shows as 0.0.0.0/0 and ::/0.