MailDingo

SPF, DKIM, DMARC and ARC

SPF explained

What SPF actually authenticates (the envelope sender, not the From line you see), how a record is evaluated, the seven results, the 10-lookup limit and why forwarded mail fails.

5 min read · updated 2026-10-26 · 10 RFC sections cited

SPF (Sender Policy Framework) answers one narrow question: was the server that handed this message to the receiver allowed to send mail for the envelope sender's domain? The domain owner publishes a list of permitted servers in DNS, the receiving server compares the connecting IP address against that list, and writes the verdict into the headers. SPF says nothing on its own about the From: address you see in your mail app. That job belongs to DMARC.

Which identity SPF checks

An SMTP conversation carries two addresses that never appear on screen: the domain the sending server introduces itself with (HELO/EHLO), and the envelope sender given in the MAIL FROM command. SPF checks those, not the header From:.

  • The MAIL FROM identity is the main one. Receivers must check it unless a HELO check already gave a definite answer (RFC 7208 §2.4). After delivery it usually survives as the Return-Path header.
  • The HELO identity may also be checked, and RFC 7208 §2.3 recommends doing so. When the envelope sender is empty, as it is for bounce messages, SPF builds the identity postmaster@<HELO name> instead.

So a message can show From: billing@example.com while SPF quietly passed for bounces.example.net. That pass is real, but it is a statement about example.net, not example.com. Whether the two domains need to match is a question for DMARC alignment.

What an SPF record looks like

The record is a DNS TXT record on the domain itself:

example.com.  TXT  "v=spf1 ip4:192.0.2.0/24 include:_spf.example.net mx ~all"

It is read left to right. Each mechanism either matches the connecting IP or does not:

Mechanism Matches when the sending IP…
ip4: / ip6: falls inside the listed address or range
a, mx is one of the domain's A/AAAA or MX hosts
include: passes the SPF record of another domain (common for email services)
exists: makes a constructed DNS name resolve (rare, used for macros)
ptr reverse DNS points into the domain (discouraged by the RFC)
all always; used last as the catch-all

Each mechanism can carry a qualifier that sets the result when it matches: + pass (the default if none is written), - fail, ~ softfail, ? neutral (RFC 7208 §4.6.2). The first match wins. If nothing matches and there is no redirect= modifier, the result is neutral (§4.7), which is why well-run domains end the record with an explicit -all or ~all.

The seven results

RFC 7208 §2.6 defines exactly seven outcomes. Each has its own page here:

Result Plain meaning
pass The IP is authorized for the domain.
fail The domain says this IP is not allowed (a - mechanism, usually -all, matched).
softfail Probably not allowed, but the owner asks for leniency (usually ~all).
neutral The owner explicitly makes no claim about this IP (?).
none No SPF record, or no usable domain to check.
temperror A transient DNS problem; a retry might succeed.
permerror The record is broken and cannot be evaluated.

A softfail or neutral is not evidence of forgery by itself. Many legitimate domains publish ~all on purpose while they find all their senders.

The 10-lookup limit

Every include, a, mx, ptr and exists mechanism, plus the redirect modifier, costs a DNS query. RFC 7208 §4.6.4 caps the total at 10 per evaluation, counting nested includes, and going over the cap produces permerror. ip4, ip6 and all are free. The same section also limits "void lookups" (queries that return nothing) to two by default.

This is the most common cause of a permerror for a domain that looks fine at first glance: it uses a mail host, a CRM, a helpdesk and a newsletter tool, each added with its own include:, and those includes pull in more includes. The record is syntactically valid but no longer evaluable. If you see spf=permerror on mail from a company you trust, this is the likely reason, and it is the sender's problem to fix.

Why forwarding breaks SPF

SPF is tied to the IP address of the last server to hand over the message. When your old university address forwards to a personal mailbox, the forwarder connects to your mailbox provider from its own IP. If it keeps the original envelope sender, the receiver checks the original domain's record, finds the forwarder's IP is not listed, and returns fail or softfail. RFC 7208 §10.3 describes exactly this.

Forwarders work around it by rewriting the envelope sender into their own domain. The widely used scheme for that is SRS (Sender Rewriting Scheme), which encodes the original address inside the new one so bounces can still find their way home. SRS is not an IETF standard; RFC 7208 Appendix D only describes the general idea of a mediator rewriting MAIL FROM. Rewriting fixes SPF, but the new domain no longer matches the From: domain, so SPF can no longer help DMARC. DKIM has to carry the message instead. The forwarding and mailing lists guide walks through what each case looks like.

What you see in the headers

Receivers record SPF in two places. The older Received-SPF field (RFC 7208 §9.1) is one result per line:

Received-SPF: pass (mx.example.net: domain of bounce@mail.example.com
 designates 192.0.2.25 as permitted sender) client-ip=192.0.2.25;
 envelope-from="bounce@mail.example.com"; helo=out1.mail.example.com;

Most large providers now put it in Authentication-Results instead, alongside DKIM and DMARC:

Authentication-Results: mx.example.net;
 spf=pass smtp.mailfrom=bounce@mail.example.com;
 dkim=pass header.d=example.com;
 dmarc=pass header.from=example.com

Read smtp.mailfrom (or envelope-from) carefully: that is the domain SPF actually vouched for. Compare it with the From: domain. Here mail.example.com and example.com share an organizational domain, so under DMARC's default relaxed mode the SPF pass counts. DMARC only uses the MAIL FROM check here, not a separate HELO check (RFC 9989 §4.4.2).

Watch out: Only trust the Authentication-Results or Received-SPF added by your own provider, normally the topmost one. Anything lower down could have been written by the sender.

What SPF does not tell you

An SPF pass means the server was authorized for some domain. Spammers publish SPF for domains they register, so a pass for an unfamiliar or look-alike domain proves nothing about honesty. An SPF fail on forwarded mail is often harmless. Read it together with DKIM and DMARC, or paste the headers into the analyser, which shows which domain each check covered and whether it lines up with the sender you see.

Got a suspicious email?

Paste its headers into the analyser. It runs on your device and explains every result on this page.

Open the analyser

Next in SPF, DKIM, DMARC and ARC: DKIM explained →