SPF

SPF validation error

SPF PermError means a receiver can't parse your domain's SPF record — bad syntax, duplicate record, or over 10 DNS lookups. Publish one corrected record.

Updated Jul 1, 2026

The short answer

An SPF validation error means a receiving mail server tried to evaluate your domain's SPF record and could not interpret it, returning a PermError (RFC 7208 §2.6.7). The usual causes are a syntax mistake, more than one SPF record on the domain, or exceeding the 10 DNS-lookup limit. Fix it by publishing a single, valid v=spf1 TXT record under those limits.

An SPF validation error is what most providers call a PermError — RFC 7208 §2.6.7 defines it as a result that "means the domain's published records could not be correctly interpreted." The receiving mail server found your v=spf1 record but could not evaluate it, so SPF fails for every message from the domain, even from a legitimate IP. This is different from a none result (no record found) or a plain fail/softfail (record evaluated fine, but the sending IP wasn't authorized).

One thing to get straight first: SPF is checked by the receiving server, but the record that's broken lives in your (the sender's) DNS. The bounce or header shows up on the recipient side; the fix always happens in your domain's DNS.

What causes an SPF validation error?

A PermError is raised by a specific set of record-level problems defined in RFC 7208 — not by an unauthorized IP. The three that account for nearly all cases:

  1. Syntax error in the record. An unrecognized mechanism, a typo (include: vs includes:), a stray character, or a record that doesn't start with v=spf1 makes the record uninterpretable. A single TXT string is also capped at 255 characters (RFC 7208 §3.3) — split long records into multiple quoted strings within the same TXT record.
  2. More than one SPF record on the domain. RFC 7208 §4.5 is explicit: "If the resultant record set includes more than one record, check_host() produces the 'permerror' result." A domain must publish exactly one v=spf1 TXT record. Two v=spf1 records (e.g. one added by your old host, one by a new sending service) is an automatic PermError.
  3. Too many DNS lookups. SPF caps DNS-querying terms at 10 per evaluation (RFC 7208 §4.6.4); void lookups are limited to 2. The include, a, mx, ptr, and exists mechanisms and the redirect modifier each count; ip4, ip6, and all do not. Chained include: statements blow past 10 fast and trigger a PermError.

(Note: a missing record produces a none result, not a validation error. If you have no SPF record at all, the fix is to publish one — but that's a different result code than the PermError described here.)

How do I fix an SPF validation error?

Work through the three causes in order:

  1. Confirm you have exactly one record. Query your TXT records and count how many start with v=spf1:
dig +short TXT example.com | grep spf1

If more than one line comes back, merge them into a single record and delete the extras.

  1. Validate the syntax. Make sure the record begins with v=spf1, every mechanism is recognized, and it ends with a single all qualifier. A typical valid record:
v=spf1 include:_spf.google.com include:sendgrid.net -all

Use ~all (softfail) or -all (hardfail) once, and don't combine qualifiers. Keep each quoted string ≤255 characters.

  1. Stay under 10 DNS lookups. Count your include, a, mx, ptr, exists, and redirect terms. If you're at or over 10, remove sending services you no longer use, replace include blocks with explicit ip4:/ip6: ranges where the provider publishes them, or flatten the record with an SPF management tool.

After editing, re-check with dig and an SPF validator, then allow for DNS propagation (typically minutes, up to the TTL of the old record) before retesting a send.

With Courier

Courier delivers via downstream email providers (e.g. SendGrid, Amazon SES, Mailgun). Add the include or IP range that your configured provider documents for SPF to your domain's single v=spf1 record — for example include:sendgrid.net for SendGrid or include:amazonses.com for Amazon SES — and verify it doesn't push you over the 10-lookup limit. Check your provider's authentication setup docs for the exact value.

FAQ

Common questions

No. A validation error is a PermError (RFC 7208 §2.6.7) — the receiver couldn't interpret your record at all, usually due to bad syntax, duplicate records, or exceeding 10 DNS lookups. A plain 'fail' or 'softfail' means the record was read correctly but the sending IP wasn't in your authorized list.

One API, every provider

Stop debugging raw provider errors

Courier connects to your email, SMS, and push providers, handles retries and failover, and surfaces delivery errors in plain language.

Reply-code definitions per RFC 7208 §2.6, §4.5, §4.6.4. Last reviewed Jul 1, 2026. Courier is not affiliated with third-party providers; error behavior may vary by implementation.