FREE · NO ACCOUNT REQUIRED

Free SPF record checker — validate SPF, count DNS lookups, expand the include chain, and find configuration issues.

SPF Checker pulls a domain's v=spf1 TXT record from DNS, recursively expands every include (typically 5–7 levels deep), parses every mechanism and qualifier, runs nine validation tests against RFC 7208, and adds an AI review of findings. Counts DNS lookups against the strict 10-lookup limit — the single most common SPF failure mode. Visualizes the full chain as an expandable tree.

01 · OVERVIEW

What gets analyzed

Six independent classes of output per check. Parsing and validation are the headlines; the recursive chain expansion and DNS-lookup counting are the differentiators that flat SPF checkers miss.

SPF record parsing (RFC 7208)

Full parse into version, mechanisms (ip4, ip6, a, mx, include, exists), qualifiers (+, -, ~, ?), modifiers (redirect, exp), and the terminal `all` directive. Each piece is structured so downstream tools can act on it.

Recursive chain expansion (Every include followed)

Every `include:` is recursively expanded to its final IP4 / IP6 lists. The chain is typically 5–7 levels deep for any domain with non-trivial email infrastructure. Microsoft.com's chain has 5 top-level includes and 7 total DNS lookups.

DNS lookup counting (Against the 10-limit)

Counts every DNS query the SPF check would consume on a receiver — the initial TXT lookup, every include, every a/mx/exists/redirect. Flags the running total against RFC 7208's hard 10-lookup limit. Exceeding it means PermError and total SPF failure.

Nine validation tests (RFC compliance)

Multiple SPF records check, lookup-count check, policy-strength check (-all vs ~all vs ?all), PTR mechanism check (deprecated), record-length check, void-lookup count, validity check, deprecated-mechanism check. Each is a separate pass/fail signal.

AI-generated findings (Severity-ranked)

Surfaces the issues that actually matter — info, warning, critical — with concrete recommendations. Catches issues that mechanical tests miss, like the malformed IP `20.` in microsoft.com's _spf1-meo.microsoft.com (real finding from the live sample).

Chain visualization (Expandable tree)

The full include hierarchy as a clickable, drillable tree. Each node shows its own SPF record, its per-mechanism lookup count, and its included children. Makes the chain depth visible at a glance — flat SPF checkers hide this.

02 · WHY THIS MATTERS

Why SPF is still the foundation in 2026

SPF has been around since 2006 (RFC 4408, then RFC 7208), it gets compared unfavorably to DKIM and DMARC, and yet it remains the single most-checked email-authentication signal — and the single most-misconfigured one. Five things that make SPF still matter:

  • Without SPF, your domain is spoofable by default. An attacker can spoof emails from your domain to your customers (or your CEO) with no technical work required. SPF is the first line of defense — it tells receivers which IPs are allowed to send mail for your domain.
  • DMARC requires SPF or DKIM alignment. DMARC is the policy layer; it makes decisions based on whether SPF and/or DKIM aligned. You can technically do DMARC with only DKIM, but in practice almost every working DMARC setup leans on aligned SPF for at least some senders.
  • Misconfiguration is silent until you investigate. An SPF record over the 10-lookup limit returns PermError — and most receivers treat that as 'no SPF', not as 'broken SPF'. Your mail keeps flowing, just without authentication. You only find out when deliverability dies or a phishing campaign succeeds.
  • Vendor includes compound over time. Every SaaS that sends mail on your behalf — marketing platform, transactional ESP, helpdesk, calendar, billing — asks you to add their `include:` to your SPF. Five vendors in, you're already at the lookup limit. Most teams discover this only after a sixth vendor is added and email stops authenticating.
  • Even Fortune 500 records have bugs. microsoft.com's SPF record (the live sample on this page) has a critical malformed entry — `ip4:20.` instead of a complete IP address — in one of its included sub-records. If Microsoft can ship a broken SPF record, so can anyone. Automated checking catches what manual review misses.
03 · HOW IT WORKS

TXT lookup, parse, recurse, validate

An SPF check is a recursive walk through DNS. We follow the same algorithm a receiving mail server would, expand every include to its terminal IPs, and count DNS lookups along the way — exactly as RFC 7208 specifies.

  • Stage 1 — Fetch the TXT record Query the target domain for TXT records. Filter for the one starting with `v=spf1`. If there are multiple, that's already a violation — a domain can only have one SPF record (we report this as a test failure).
  • Stage 2 — Parse mechanisms left-to-right Each space-separated token is a mechanism or modifier. Mechanisms get a qualifier prefix (default `+`); modifiers use `=` syntax. Order matters — SPF evaluates left-to-right and stops at the first match.
  • Stage 3 — Recursively expand includes For each `include:domain`, fetch that domain's SPF record and recurse. Track the lookup count globally — every recursive call adds to it. Build the chain as a tree for visualization.
  • Stage 4 — Count DNS lookups Increment for each include, a, mx, exists, redirect — anything that requires a DNS query. ip4/ip6/all don't increment. Compare against the 10-limit; anything over is fatal (PermError).
  • Stage 5 — Run validation tests Nine checks against RFC 7208: lookup count, policy strength, PTR usage, record length, void lookups, deprecated mechanisms, etc. Each is pass/fail with an explanation.
  • Stage 6 — AI review Feed the parsed record, expanded chain, and test results to the analyzer. Surfaces severity-ranked issues — info, warning, critical — with concrete fixes. Catches things mechanical tests don't, like malformed IP entries inside deeply-nested includes.
04 · TERMINOLOGY

SPF vs DKIM vs DMARC — what each one actually does

These three terms get used interchangeably and conflated constantly. They're not interchangeable — they solve different problems and complement each other. The shortest accurate framing: SPF authorizes IPs, DKIM signs messages, DMARC sets policy. You generally want all three.

  • SPF — Sender Policy Framework Lists which IP addresses are allowed to send mail for your domain. Lives in DNS as a TXT record. IP-based — checks the connecting server's IP against your published list. Easy to set up; brittle when forwarded (forwarding changes the sending IP, breaking SPF).
  • DKIM — DomainKeys Identified Mail Cryptographically signs the outgoing message body and selected headers. The signature travels with the message; receivers verify it using a public key published in DNS at `<selector>._domainkey.<domain>`. Content-based — survives forwarding, since the signature stays attached to the message. Harder to set up than SPF, more reliable in practice.
  • DMARC — Domain-based Message Authentication, Reporting, and Conformance Tells receivers what to do when SPF or DKIM fails — none (just monitor), quarantine (junk it), or reject (block entirely). Lives at `_dmarc.<domain>` as a TXT record. Adds reporting (rua, ruf) so you find out who's being authenticated and who isn't. Policy-based — coordinates the two underlying mechanisms.
  • How they fit together A mail flow that's properly authenticated has: SPF allowing the sender's IP, DKIM signature verifying with a matching DNS key, AND DMARC policy that aligns the From: domain with the SPF/DKIM-authenticated domain. Receivers grade the message based on all three; DMARC's `p=reject` is the strongest signal you can publish.
  • What this tool covers SPF only. For DKIM verification, see the DKIM Checker. For DMARC policy parsing and report-URI validation, see the DMARC Checker. For a combined health view across all three, see the Email Authentication tool.
05 · MECHANISMS

Every SPF mechanism, explained

An SPF record is a sequence of mechanisms, evaluated left-to-right. The first match wins; if nothing matches, the terminal `all` decides. Each mechanism authorizes a different way of identifying a sender:

  • v=spf1 — Version (required, first) Identifies the record as SPF version 1 — the only version that exists. Must be the very first token in the record. Without it, the TXT record is just text, not SPF.
  • ip4: / ip6: — Allow specific IPs Allows the listed IPv4 or IPv6 address (or CIDR range) to send mail. `ip4:192.0.2.0/24` and `ip6:2001:db8::/32`. Does NOT count toward the 10-lookup limit — these are static and require no DNS query. The cheapest mechanism in terms of lookup budget.
  • a / a:domain — Allow A-record IPs Allows IPs found in the A (or AAAA) records of the current domain (bare `a`) or a specified domain (`a:example.com`). Counts as one DNS lookup. Used when the mail server's IPs can be derived from existing DNS.
  • mx / mx:domain — Allow MX-host IPs Allows IPs of MX-record hosts for the current domain or a specified one. One DNS lookup for the MX query, plus one each per MX target (which can stack — a domain with 4 MX servers consumes 5 lookups from a single `mx` mechanism).
  • include:domain — Include another SPF record Recursively fetches and evaluates another domain's SPF record at this position. This is what makes SPF chains deep. Counts as one lookup, plus every lookup inside the included record. The biggest source of lookup-limit exhaustion.
  • exists:domain — Allow if DNS returns any A record Passes if a DNS query for the given name returns any A record. Used in macro-based SPF for sender-specific authorization. Rare in practice. One lookup each.
  • ptr — DEPRECATED, never use Checks the sender's reverse DNS (PTR record) against the domain. Slow, unreliable, and easy to spoof. Formally deprecated in RFC 7208. The presence of `ptr` in your SPF record is itself a quality signal — none of the modern best-practice setups include it.
  • all — The terminal catch-all Matches anything not caught by previous mechanisms. Always the last token. The qualifier on `all` is what defines your SPF policy strength — see section 06.
  • redirect=domain — Replace with another record (modifier) Discards this record and uses the target domain's SPF instead. Used by SaaS platforms to consolidate SPF management. Counts as one lookup. Can't coexist with an `all` mechanism in the same record.
  • exp=domain — Custom explanation (modifier) Specifies a domain whose TXT record provides a custom explanation message for failures. Almost never used in practice; receivers don't typically display it.
06 · QUALIFIERS

What -all, ~all, ?all, and +all actually do

Every mechanism can carry a qualifier prefix. The qualifier tells receiving mail servers what to do when the mechanism matches. The qualifier on `all` is the most consequential — it defines your overall SPF policy strength.

  • + (Pass) — The default Mail passes SPF. This is the implicit qualifier if no prefix is given — `ip4:192.0.2.1` and `+ip4:192.0.2.1` are identical. You almost never write `+` explicitly; it's understood.
  • - (Fail / hard fail) Mail FAILS SPF — receivers should reject. Used with `-all` at the end of a record for strict policy. Microsoft.com's record ends in `-all`, which is the gold-standard SPF posture: only explicitly listed senders are authorized; everyone else is rejected.
  • ~ (SoftFail) Mail fails SPF, but receivers should accept it with a soft mark (typically marked as suspicious or sent to junk, but not outright rejected). Used with `~all` during a transition or while testing — you want telemetry without breaking legitimate-but-misconfigured senders.
  • ? (Neutral) No policy expressed. Used with `?all`, which is functionally identical to not having an SPF record at all from a policy perspective. Rare; usually a sign someone forgot to finish configuring.
  • + (Pass) on `all` — DANGEROUS `+all` means 'everyone is authorized to send mail for this domain' — which defeats the entire purpose of SPF and is actively worse than having no record. If you see `+all` in a production SPF, treat it as an emergency: the domain is configured to allow universal spoofing.
  • The policy hierarchy `-all` (strict) > `~all` (testing) > `?all` (neutral, useless) > `+all` (disastrous). Production domains should land on `-all` once SPF is correctly configured. Use `~all` only while bootstrapping — long-term reliance on softfail leaves your domain partially spoofable.
07 · THE 10-LOOKUP LIMIT

Why "too many DNS lookups" is the most common SPF failure

RFC 7208 limits an SPF check to 10 DNS lookups total — including the original record fetch, all include expansions, every a/mx/exists/redirect query. Exceed it and the entire SPF check returns PermError, regardless of what your actual record says. Most receivers treat PermError as 'no SPF', meaning your authentication silently disappears.

  • What counts toward the limit Every `include:` (one + everything inside it). Every `a`, `mx`, `exists`, and `redirect=` directive (one each). Every PTR query inside `ptr` mechanisms (deprecated, but still counts if present). The initial TXT lookup for `v=spf1` is technically free, but `include:` chains consume budget fast.
  • What doesn't count `ip4:` and `ip6:` directives — these are static and require no DNS query. The terminal `all` — also no query. This is why SPF flattening works: replacing `include:` chains with explicit ip4/ip6 lists eliminates lookups entirely.
  • How fast it adds up A single popular SaaS include can consume 4–6 lookups on its own (their own chain has includes). Add 3 vendors and you're at 12 — over the limit. Office 365's `include:spf.protection.outlook.com` alone counts as 1 (just the outer include), but vendors that chain through Exchange Online or similar can easily blow the budget.
  • Why exceeding it is silent PermError isn't a hard reject — most receivers just treat it as 'we couldn't determine SPF', which is essentially equivalent to having no SPF record. Your mail keeps flowing, deliverability gradually degrades, and the failure mode is invisible until DMARC reports start showing fail counts. By then, you've been authenticating no mail for weeks.
  • How to fix it — by effort Easiest: audit and remove unused includes (vendors you no longer use, forgotten tools, deprecated mail relays). Medium: consolidate via a single managed-SPF provider (EasyDMARC, dmarcian, Valimail) that flattens chains for you. Hardest but most precise: maintain your own flattened SPF — replace `include:` chains with explicit ip4/ip6 lists, and monitor for upstream IP changes.
  • Why microsoft.com is at 7/10 Microsoft splits their SPF across 5 includes (`_spf-a` through `_spf-c`, plus `_spf-ssg-a.msft.net` and `_spf1-meo`). Each one expands into more lookups. They've already used 7 of the 10 allowed — adding one more vendor would risk pushing over the limit. This is a real cost of SPF that grows over time.
08 · API

Use this programmatically

Every field — parsed record, expanded chain, test results, AI findings — is available as JSON. Useful for pre-DMARC deployment checks, email-migration verification, vendor onboarding gates, and continuous SPF monitoring. Rate-limited per IP on the free tier.

JavaScript (fetch)
const res = await fetch(
  'https://api.domainscan.in/v1/spf?domain=microsoft.com'
);
const spf = await res.json();

console.log(spf.spf);                          // raw SPF record
console.log(spf.parsed.qualifier);             // '-all' (strict policy)
console.log(spf.expanded.lookupCount);         // 7  (of 10 max)
console.log(spf.expanded.includes.length);     // 5  (top-level includes)

// Aggregate every authorized IPv4 / CIDR across the full chain
const allIp4 = new Set();
const walk = (node) => {
  node.ip4List?.forEach(ip => allIp4.add(ip));
  node.includes?.forEach(inc => walk(inc.expanded));
};
walk(spf.expanded);
console.log(allIp4.size);                      // ~80 IPs authorized for microsoft.com

// Did any test fail?
const failures = spf.tests.filter(t => !t.passed);
if (failures.length) {
  console.warn('SPF issues:', failures.map(f => f.test));
}

// Critical AI findings — the actionable ones
const critical = spf.AiAnalysis.issues.filter(i => i.severity === 'critical');
critical.forEach(i => console.error(i.title, '—', i.recommendation));
Response schema (abridged)
{
  "spf":    "v=spf1 include:_spf-a.microsoft.com ... -all",
  "parsed": {
    "version":    "v=spf1",
    "qualifier":  "-all | ~all | ?all | +all",
    "mechanisms": { "ip4": [], "ip6": [], "include": ["..."], "a": [], "mx": [] },
    "modifiers":  [],
    "directives": ["include:...", "-all"]
  },

  "tests": [
    { "test": "Multiple SPF Records",      "result": "...", "passed": true },
    { "test": "Too Many DNS Lookups",      "result": "...", "passed": true },
    { "test": "SPF Policy Strength",       "result": "...", "passed": true },
    { "test": "Number of DNS Lookups",     "result": "...", "passed": true },
    { "test": "No 'PTR' Mechanism",        "result": "...", "passed": true },
    { "test": "SPF Record Length",         "result": "...", "passed": true },
    { "test": "Number of Void Lookups",    "result": "...", "passed": true },
    { "test": "SPF record validity",       "result": "...", "passed": true },
    { "test": "No Deprecated Mechanisms",  "result": "...", "passed": true }
  ],

  "expanded": {
    "domain":      "string",
    "spfRecord":   "string",
    "lookupCount": "number (total DNS lookups across the chain)",
    "ip4List":     ["string"],
    "ip6List":     ["string"],
    "mechanisms":  [{ "type": "...", "qualifier": "+|-|~|?", "value": "..." }],
    "includes":    [
      {
        "domain":   "string",
        "expanded": { /* recursive: same shape */ }
      }
    ]
  },

  "AiAnalysis": {
    "issues": [
      {
        "severity":       "info | warning | critical",
        "title":          "string",
        "description":    "string",
        "recommendation": "string"
      }
    ],
    "quick_recommendations": ["string"]
  }
}
09 · USE CASES

How teams use SPF Checker

Six patterns we see most often:

Pre-DMARC deployment (Setup)

Before publishing a DMARC policy with `p=quarantine` or `p=reject`, audit your SPF. A misconfigured SPF + strict DMARC = legitimate mail rejected. Fix the SPF first, then ratchet up DMARC.

Email-migration verification (Migration)

Moving from G Suite to Office 365 (or vice versa, or onto a new ESP). Add the new include, verify it doesn't push you over 10 lookups, then remove the old one. Re-check before flipping production traffic.

Vendor onboarding gate (Procurement)

A new SaaS asks you to add their `include:` to your SPF. Run the check after adding to verify the lookup count stays under 10. Some vendors publish wildly bloated SPF records — better to catch it before deploying.

Deliverability incident response (Incident)

Mail to a key customer is bouncing or landing in spam. SPF check is the first thing to run — PermError due to lookup overrun is one of the most common silent causes of deliverability degradation.

M&A and vendor due diligence (Diligence)

Acquiring a company or evaluating a vendor's email infrastructure. SPF strength (`-all` vs `~all` vs `?all`) and chain quality are leading indicators of how seriously they take email security.

Continuous monitoring (Operations)

Cron the API against your domains. Alert when lookup count creeps toward 10, when a test starts failing, or when an AI critical issue appears. Catches the silent drift that breaks SPF over months.

10 · QUESTIONS

Common questions

  • What's the difference between SPF, DKIM, and DMARC? SPF lists which IPs can send mail for your domain (IP-based, lives in a TXT record). DKIM cryptographically signs the outgoing message (content-based, signature travels with the email). DMARC tells receivers what to do when SPF or DKIM fails (policy-based, lives at `_dmarc.<domain>`). They're complementary, not interchangeable — proper email authentication uses all three.
  • What does "too many DNS lookups" mean and how do I fix it? RFC 7208 limits SPF checks to 10 DNS lookups. Every `include:`, `a`, `mx`, `exists`, and `redirect=` counts; `ip4:` and `ip6:` do not. Exceed 10 and the entire SPF check returns PermError, which most receivers treat as 'no SPF'. Fix it by: removing unused includes, consolidating via a managed SPF service (EasyDMARC, dmarcian, Valimail), or maintaining a flattened SPF record where `include:` chains are replaced with explicit IP lists.
  • What's the difference between -all and ~all? `-all` is strict — receivers should reject mail that fails SPF. `~all` is soft-fail — receivers should accept the mail but mark it suspicious (typically junk it). `-all` is the production goal; `~all` is appropriate during initial deployment or while transitioning between providers. `?all` (neutral) is essentially the same as having no SPF record. `+all` allows everyone to spoof your domain — never use it.
  • Can I have multiple SPF records? No — RFC 7208 explicitly forbids it. A domain must have exactly one SPF record. Multiple SPF TXT records cause a PermError on the entire check, just like exceeding the lookup limit. If you find yourself wanting two records (e.g., one for marketing and one for transactional mail), use a single record with multiple `include:` directives instead.
  • What is SPF flattening and should I use it? SPF flattening replaces `include:` chains with explicit `ip4:` / `ip6:` lists. The result has zero recursive DNS lookups, which makes the 10-limit irrelevant. Tradeoffs: you must monitor for upstream IP changes (vendor adds new sending infrastructure → your flattened record gets stale → mail starts failing). Use it when you have no other choice (more than 10 lookups required); otherwise, prefer fewer includes. Managed services (EasyDMARC, dmarcian, Valimail) handle the monitoring automatically.
  • Do I still need SPF if I have DKIM and DMARC? Technically you can pass DMARC with only DKIM aligned. Practically, SPF is the cheapest authentication signal to publish (just a TXT record), receivers still weigh it independently in their spam-scoring algorithms, and forwarded mail (where DKIM helps and SPF breaks) is the minority case. Publish all three. The marginal effort is small; the benefit is meaningful.
  • Why does my legitimate mail still go to spam despite valid SPF? SPF passing is necessary, not sufficient. Receivers also weigh sender reputation (IP and domain), DKIM, DMARC alignment, content signals (links, language patterns), engagement (do recipients open and reply?), and many other factors. A perfect SPF record won't save mail from a low-reputation sender, and forwarding breaks SPF entirely (the forwarder's IP isn't in your record). If SPF is valid but mail still spams, look at DKIM coverage, DMARC alignment, and sender reputation tools (Google Postmaster, Microsoft SNDS).
  • What does the ptr mechanism do and why is it deprecated? `ptr` checks the sender's reverse DNS (PTR record) against the SPF domain. Two problems: it's slow (every check requires an extra DNS round-trip), and PTR records are owned by the IP block holder, not the sender — so the trust model is fundamentally weak. RFC 7208 formally deprecates `ptr`; the existence of `ptr` in a published SPF record is itself a red flag indicating an old or low-quality configuration.