SPF Observatory 2026

A standing measurement of what SPF records actually publish across the 320 domains someone ran through the public Humerly audit in the last 90 days. Every figure is read from a pinned corpus file and carries the window, the resolver set and the exclusions that produced it. Rates here are upper bounds, not internet-wide rates: these are domains somebody had a reason to check.

Methodology

Read this before the findings. Every number on this page is read from spf-corpus-2026-09-08.json (sha256 088815037fd3d814…); nothing here is authored, and nothing is derived that the file does not already state.

SampleOne row per domain: the most recent audit_reports_v2 report for that domain, lowercased. Domains reach this table by someone running them through the public Humerly deliverability audit.
Windowlast 90 days from measured_at
Measured at8 September 2026, 14:09 UTC
Completed at8 September 2026, 14:10 UTC
ResolversEngine walk: this host's configured recursive resolver. Resolver-disagreement probe: 1.1.1.1, 8.8.8.8, 9.9.9.9 and the zone's authoritative nameserver queried directly.
DeduplicationDISTINCT ON (lower(domain)) ordered by created_at DESC. A domain audited nine times would otherwise weight the corpus nine times, and re-audits are not independent: people re-run after a change, so repeats skew toward domains that were failing.

Exclusions

Rule: rows with source = synthetic_monitor, and these seven domains: humerly.com, vgcbit.com, jaldok.com, b.jaldok.com, tarniko.com, barniva.farm, bbc.co.uk.

The source exclusion removed ZERO rows: no row in audit_reports_v2 carries source='synthetic_monitor'. Live values are web, outreach and remeasure. The rule is declared because it was specified, and is recorded as inert rather than quietly dropped. Of the seven named domains, six were present in the window; barniva.farm has zero rows in the table at all.

The arithmetic follows from that note: 326 domains in the window, 320 after exclusions — six removed, not seven, because one of the seven named domains had no rows to remove.

Limitations

Engine

lookup limit10
spf findings sha2564092383f9924ad48
spf tree sha256d8a0793d5ed8c686
void limit sourceRFC 7208 s4.6.4, vendored core/rfc/rfc7208.txt (sha256-verified)
void lookup limit2

What an evaluator returned

One verdict per domain, 320 in total.

VerdictDomainsShareMeaning
pass25278.75%an SPF record was found and evaluated without error
fail3510.94%no usable record — see spf-no-record below
permerror165.00%a permanent error: the record exists but cannot be evaluated
invalid103.12%the record was found but did not parse
temperror51.56%a temporary DNS error during evaluation
timeout20.62%the lookup did not complete in time

How domains end their record — a distribution, not a defect rate

162 of 320 domains (50.62%) end their record in ~all. That is the largest single number here and it is the easiest one to misread. ~all is a valid qualifier: RFC 7208 §8.5 asks receiving software not to reject a message on that result alone. What this counts is what domain owners chose, not how many of them are broken.

EndingDomainsShare of 320
~all softfail16250.62%
?all neutral10.31%
+all pass-everything00.00%
no record at all3510.94%

The corpus does not record a -all count, so this page does not state one. Subtracting the rows above from the 285 domains that have a record would give a number nobody measured, and would assume these categories are mutually exclusive and exhaustive. They may be; the file does not say so.

Findings, per domain

Counted per domain, not per occurrence: a record with three duplicate includes contributes one.

Registry keyDomainsShareSeverity
spf-softfail-vs-fail16250.62%warn
spf-no-record3510.94%fail
spf-nested-include-counted-twice154.69%warn
spf-too-many-dns-lookups134.06%fail
spf-multiple-records103.12%fail
spf-record-differs-across-resolvers72.19%warn
spf-record-syntax-and-encoding72.19%fail
spf-include-lookup-failed61.88%fail
spf-include-has-no-spf41.25%fail
spf-neutral-all10.31%warn
spf-ptr-mechanism10.31%warn
spf-plus-all00.00%fail
spf-void-lookups00.00%fail

Rules that do not exist yet

Five of the eighteen registry keys have no rule implemented. They are absent from the counts above, not zero — a rule nobody wrote cannot find anything, and rendering it as 0% would claim no domain has the problem.

Registry keyDomainsShareSeverity
spf-a-mechanism-behind-cdn-proxynot measurednot measuredwarn
spf-flattening-risksnot measurednot measuredinfo
spf-ip-range-too-broadnot measurednot measuredwarn
spf-mx-mechanism-costnot measurednot measuredinfo
spf-return-path-domain-mismatchnot measurednot measuredwarn

What this page deliberately does not show

The corpus carries five example domains for each finding. They are real third parties who ran the public audit, and naming them here as having a broken record is not something they agreed to. The examples stay in the corpus, where they serve reproduction, and off this page.

Reviewed by Venkat Nookala, last reviewed 2026-09-08.