Skip to content

SPF ~all vs -all: Softfail or Hardfail?

Short answer

-all is hardfail: unlisted senders are explicitly unauthorized. ~all is softfail: unlisted senders are suspicious but should be accepted and marked. ?all is neutral and says nothing. +all authorizes the entire internet and must never be published. Start at ~all, verify with DMARC reports, then move to -all.

Check it yourself
SPF Checker
Validate SPF syntax and count the 10-lookup limit live

The qualifier on the final all mechanism is the default result for any sending IP that did not match anything earlier in your record. It is the only part of an SPF record that expresses intent rather than fact, and it is where most of the argument about SPF lives.

What does each qualifier mean?

TermSPF resultWhat you are telling receiversTypical receiver behavior
-allfailThis IP is not authorized to send as my domain.Reject at SMTP, or accept and file as spam. RFC 7208 permits either.
~allsoftfailProbably not authorized, but I am not certain yet.Accept the message, record the softfail, weight it in filtering.
?allneutralI am making no assertion about this IP.Treated the same as having no SPF policy at all.
+allpassEvery IP on the internet is authorized to send as my domain.SPF passes for anyone, including spoofers.

Note that RFC 7208 does not require receivers to reject on fail. It says a fail result means the client is not authorized and the receiver may reject; a softfail message should be accepted but may be subjected to closer scrutiny. In practice large mailbox providers rarely reject on SPF fail alone anymore — they feed the result into a broader decision. Small self-hosted MTAs and appliances, on the other hand, often still reject outright on -all, which is exactly where hardfail bites you.

Why is +all dangerous?

+all makes SPF pass for every sender on the internet. That is worse than publishing no SPF record at all, because a domain with no SPF record produces a none result that receivers treat with suspicion, while +all produces an affirmative pass that some filters read as a positive signal.

It gets worse if you also publish DMARC. DMARC passes when the message has an aligned SPF pass or an aligned DKIM pass. With +all, anyone who puts your domain in both the MAIL FROM and the From: header gets an aligned SPF pass, and therefore a DMARC pass, from any IP they like. Your DMARC policy becomes a rubber stamp on other people's phishing. If you find +all in a record, it is almost always a copy-paste accident or an "it was blocking our mail so we fixed it" incident — remove it the same day.

The same reasoning applies to +mx, +a, or any mechanism prefixed with + on ranges you do not control. + is the default qualifier, so include: already means +include: — the danger is specifically in applying it to all.
# Find the qualifier on any domain's record
dig +short TXT example.com | grep spf1

# Real examples you can check right now
dig +short TXT google.com | grep spf1
# "v=spf1 include:_spf.google.com ~all"

dig +short TXT spf.protection.outlook.com
# "v=spf1 ip4:40.92.0.0/15 ... ip6:2a01:111:f400::/48 ... -all"
Reading the all qualifier from the command line
SPF Checker
Validate SPF syntax and count the 10-lookup limit live

What breaks under -all that survives under ~all?

SPF authenticates the SMTP envelope sender against the connecting IP. Anything that relays your mail from an IP you did not authorize produces a fail, and hardfail is where that becomes visible as a bounce rather than a filtering nudge.

  • Plain forwarding. A user auto-forwards from their work address to a personal mailbox. The forwarding server relays your message from its own IP with your MAIL FROM intact, and SPF fails at the final destination. SRS rewriting fixes this, but only if the forwarder implements it.
  • Mailing lists. Many lists rewrite the envelope sender (which fixes SPF) but modify the body or subject (which breaks DKIM). Some do neither.
  • Vendors you forgot. Invoicing systems, backup monitoring, an appliance sending alerts from the office IP, a legacy application server relaying through a shell account. These are invisible until they bounce.
  • Marketing platforms using your domain in the Return-Path without having been added to the record — common right after a platform migration.
  • Multi-region ESP sending. A vendor that adds an EU or APAC range you never included in a flattened record.

Under ~all these all still deliver, usually to the inbox, and show up in your DMARC aggregate reports as SPF-failing sources. Under -all some receivers will bounce them. That difference — visibility versus breakage — is the entire argument for starting at softfail.

How does DMARC change the calculation?

This is the part people get wrong. DMARC does not distinguish between SPF softfail and hardfail. For DMARC, the only thing that matters is whether SPF *passed* and whether the passing domain aligned with the From: header domain. fail, softfail, neutral, and none are all equally "not a pass". Your DMARC policy — p=none, p=quarantine, or p=reject — is what decides what happens to unauthenticated mail.

So once DMARC is enforcing, -all adds much less than people assume against mail that spoofs your From: header. What -all still does is cover the cases DMARC does not: mail that uses your domain in the envelope sender but someone else's domain in From:, receivers that check SPF but not DMARC, and reputation systems that weight an explicit fail more heavily than a softfail. That is a real but modest benefit, and it comes with the forwarding risk above.

SituationWith ~allWith -all
Spoofed From: at your domain, DMARC p=rejectRejected by DMARCRejected by DMARC — same outcome
Forwarded legitimate mailDelivered, softfail recordedMay be rejected by strict receivers
Envelope-only abuse of your domainWeak signalExplicit unauthorized signal
Receiver checks SPF but not DMARCAccepted with a penaltyLikely rejected
Forgotten legitimate senderDelivers; visible in DMARC reportsBounces; you find out from an angry user

What should you publish?

A staged rollout, in the same spirit as the DMARC policy rollout. Do not skip straight to -all on a domain whose sending inventory you cannot list from memory.

  1. Publish ~all with a complete-as-you-know-it list of senders, and publish DMARC with p=none and an rua= address at the same time. Build it with the SPF generator and the DMARC generator.
  2. Collect aggregate reports for at least two weeks, and longer if you have monthly or quarterly batch runs. Every SPF-failing source in those reports is either something to add to the record or something to shut down.
  3. Add the legitimate sources, keeping the total DNS-querying mechanism count at or below ten — see SPF PermError: too many DNS lookups if you run out of room.
  4. Tighten DMARC to p=quarantine, then p=reject, watching reports at each step. Do this before touching the SPF qualifier — DMARC is where the enforcement value is.
  5. Once reports show a clean inventory and DMARC is enforcing, switch ~all to -all if you want the extra signal. Keep watching reports for a couple of weeks afterwards.
For a domain that sends no mail at all, skip the staging: publish v=spf1 -all plus a DMARC record with p=reject. There is nothing legitimate to break, and an unused domain is a favourite for spoofing. Do the same on parked subdomains.

How do you confirm what receivers actually saw?

Send a test message to an external mailbox and read the Authentication-Results header on the received copy. You are looking for the SPF result and the domain it was checked against:

Authentication-Results: mx.example.net;
       spf=pass (sender IP is 209.85.220.41)
           smtp.mailfrom=example.com;
       dkim=pass header.d=example.com;
       dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=example.com
What a passing result looks like — note smtp.mailfrom is the SPF-checked domain

A softfail or fail here names the IP that was rejected, which is the fastest way to identify a forgotten sender. Paste the full headers into the email header analyzer for a breakdown, and use the deliverability test to check SPF, DKIM, DMARC, MX, and PTR together before you tighten anything.

Frequently asked questions

Will -all get my mail rejected by Gmail or Outlook?
Not your own mail, if the sending IPs are in your record. The risk with -all is mail that legitimately leaves your domain from an IP you did not authorize — most often forwarded messages and forgotten vendors. Large providers generally weight an SPF fail rather than rejecting on it alone, but smaller receivers and on-premise appliances often do reject.
Does ~all weaken my anti-spoofing protection?
Against messages that forge your From: header, almost not at all, because DMARC makes that decision and DMARC treats softfail and fail identically. Where ~all is weaker is with receivers that evaluate SPF without DMARC, and against abuse that uses your domain only in the envelope sender.
What is the difference between ?all and having no SPF record?
A neutral result and no record at all are meant to be treated the same way by receivers, so ?all buys you nothing over an absent record. It is occasionally used as a deliberate placeholder during a migration, but there is rarely a good reason to leave it in place.
Can I use -all if my users forward their mail?
You can, but expect some of that forwarded mail to bounce or land in spam at the final destination. If the forwarding is inside your control, enable SRS on the forwarding host so the envelope sender is rewritten to a domain you do authorize. If users are forwarding to personal accounts you do not control, softfail is the safer choice.
Should the qualifier match on subdomains?
SPF does not inherit, so each sending subdomain needs its own record and its own qualifier. A reasonable pattern is a permissive record on the sending subdomains you actively manage and a bare "v=spf1 -all" on subdomains that never send, which removes them as spoofing targets at no risk.
Does -all fix a PermError?
No. If your record exceeds the ten DNS-lookup limit or has two v=spf1 records, evaluation stops with permerror before the all mechanism is ever reached, and the qualifier is irrelevant. Fix the structural problem first, then decide on the qualifier.

Last updated: 2026-09-01