spf

Do Subdomains Need Their Own SPF Record?

SPF does not climb from a subdomain to your root domain, so a subdomain with no record returns "none" and is trivially spoofable. This guide shows why SPF inheritance is a myth, how to write per-subdomain records, how to lock down subdomains that never send mail, and how the DMARC sp= tag fills the gap SPF leaves open.

Jul 3, 20267 min read

Short answer: yes, every subdomain that sends email needs its own SPF record, and every subdomain that never sends mail should be locked down with one too. SPF does not inherit from your organizational domain the way DMARC does. If mail.example.com has no SPF record of its own, a check against it returns none, not the policy you set on example.com. That gap is exactly what spoofers look for.

Reads public DNS only. Nothing is stored unless you save the domain to an account.

SPF checks one exact name, and it never climbs

An SPF evaluation, defined in RFC 7208, looks at the domain in the SMTP envelope (the MAIL FROM, also called the return-path or envelope-from) and, separately, the HELO/EHLO name the sending server presents. The receiver takes that domain, does a single TXT lookup at that exact name, and evaluates whatever record it finds there.

There is no tree walk. If the envelope domain is news.example.com, the receiver queries news.example.com for a v=spf1 TXT record and nothing else. It does not fall back to example.com. It does not merge the two. This is the single most misunderstood fact about SPF, and it trips up teams who assume the root record protects everything beneath it.

Contrast this with DMARC, which is built to walk up. DMARC evaluates the domain in the visible From: header, and if that subdomain has no DMARC record, the receiver climbs to the organizational domain and applies the parent policy. SPF has no equivalent mechanism. That single design difference is why people who "only set up SPF once, at the top" leave a hole under every subdomain.

What "none" actually means

When a receiver looks up SPF for a subdomain and finds no record, the result is none, which literally means "the domain published no SPF policy, so we cannot make a statement." It is not a soft fail, not a hard fail, just an absence. A none result gives the receiver nothing to reject on. Combined with a From: header on that same subdomain, an attacker can send mail that passes basic checks and, depending on your DMARC configuration, lands in inboxes. If you want to understand the full anti-spoofing picture, our guide on how to stop email spoofing of your domain puts SPF, DKIM and DMARC in context.

Every sending subdomain needs its own record

If you send transactional mail from mail.example.com, marketing from news.example.com, and helpdesk replies from support.example.com, each of those is a distinct DNS name and each needs its own v=spf1 record listing the servers allowed to send for it.

A typical transactional subdomain using a provider like Amazon SES might look like this:

mail.example.com. IN TXT "v=spf1 include:amazonses.com -all"

A marketing subdomain using a separate platform is independent:

news.example.com. IN TXT "v=spf1 include:sendgrid.net -all"

Notice the records do not have to match, and they should not be copies of the root. Each subdomain authorizes only the infrastructure that actually sends for it. That keeps your lookup count low and your policy precise. For the mechanics of building a clean record, see how to set up SPF, and if you are already near the limit, fix SPF too many DNS lookups covers the ten-lookup ceiling that applies per record, per name.

The root record does not cover the children

It is worth stating plainly because so many people get it backwards. This record:

example.com. IN TXT "v=spf1 include:_spf.google.com -all"

protects mail sent from example.com. It does nothing for mail.example.com, news.example.com, or any other child. Each of those is evaluated on its own name and, without its own record, returns none.

Lock down subdomains that never send mail

Most organizations have far more subdomains than they realize: www, app, vpn, dev, staging, cdn, old marketing microsites, and dozens of DNS names that exist for web or infrastructure reasons and will never legitimately originate email. Every one of them is a spoofable envelope domain until you say otherwise.

The fix is a hard-fail SPF record that authorizes nothing:

dev.example.com. IN TXT "v=spf1 -all"

That record says "no server on earth is allowed to send mail as this name." A receiver that sees mail claiming to come from dev.example.com now gets an explicit fail instead of a permissive none, and can reject it outright. Publishing v=spf1 -all on non-sending subdomains is one of the cheapest, highest-value hardening steps you can take.

Wildcards help, but only partway

You can publish a wildcard TXT record to catch subdomains you have not explicitly named:

*.example.com. IN TXT "v=spf1 -all"

This is useful, but understand its limits. A DNS wildcard only synthesizes a record for a name that does not exist in the zone at all. The moment a subdomain has any record of its own, of any type, that name exists, so a query for its SPF returns empty rather than the wildcard value. This is why your web and infrastructure subdomains are usually not covered: they already have A or CNAME records, so the wildcard never applies to them. Any subdomain that resolves, and certainly any that sends mail, must carry its own explicit SPF record. Wildcards also do not help with the HELO identity of servers that present a specific hostname. Treat the wildcard as a safety net for the long tail, not as a substitute for named records on the subdomains that matter.

How DMARC's sp= tag fills the SPF gap

Because SPF cannot climb, DMARC is what actually gives you organization-wide subdomain coverage. In a DMARC record, the sp= tag sets the policy for subdomains that do not publish their own DMARC record.

_dmarc.example.com. IN TXT "v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc@example.com"

Here p=reject governs the organizational domain and sp=reject governs every subdomain that has not overridden it. If you omit sp=, subdomains inherit the p= value by default. This is the safety layer that catches spoofed subdomains you forgot to lock down at the SPF level, because DMARC will reject a message whose From: is an unauthenticated subdomain even when that subdomain's SPF returned none.

The two systems work together. SPF -all records make individual subdomains explicitly unauthorized at the envelope level. DMARC sp=reject provides a blanket header-level policy for anything you missed. Belt and braces. Our walkthrough on how to set up DMARC explains the full record, and dmarc policy none quarantine reject covers choosing the right enforcement level before you turn sp= up to reject.

A caution on sp= and alignment

If you set sp=reject while a legitimate subdomain is still sending without proper SPF or DKIM alignment, you will start rejecting your own mail. Roll enforcement forward deliberately: publish records for every sending subdomain first, confirm they pass and align, then tighten sp=. Avoid the temptation to use a permissive +all anywhere to make failures go away, which is a self-inflicted wound explained in why +all in SPF is dangerous.

Verify the whole tree, not just the root

The practical takeaway is that "we have SPF" is not a domain-level statement, it is a per-name statement. You need to check each sending subdomain individually and confirm three things: the record exists, it lists the correct sending infrastructure, and it ends in -all. Then confirm your non-sending subdomains return an explicit fail and that your DMARC sp= tag backs the whole thing up. Run your domain and each subdomain through the checker above to see the real result a receiver would compute, rather than assuming inheritance that does not exist.

Frequently asked questions

Does SPF inherit from the parent domain like DMARC does?

No. SPF has no inheritance or tree walk. It performs a single TXT lookup at the exact envelope domain being checked. A subdomain with no record of its own returns none, regardless of what the parent domain publishes. Only DMARC climbs to the organizational domain, using the sp= tag for subdomains.

What SPF record should I put on a subdomain that never sends email?

Publish v=spf1 -all on it. That authorizes zero senders and turns any spoofed mail from that name into an explicit fail a receiver can reject, instead of a permissive none. Do this for every DNS name that exists for web or infrastructure reasons and will never originate mail.

If I set sp=reject in DMARC, do I still need SPF on each subdomain?

Yes, for any subdomain that actually sends mail. DMARC needs an aligned SPF or DKIM pass to let legitimate mail through, so a sending subdomain still needs a valid SPF record. sp=reject only handles subdomains that send nothing and would otherwise be spoofed; it does not replace per-subdomain SPF for real senders.

Will a wildcard SPF record protect all my subdomains?

Partially. A *.example.com TXT record with v=spf1 -all catches subdomains that have no TXT records of their own, but it stops applying the moment a subdomain publishes any TXT record. So it is a useful safety net for the long tail, not a replacement for explicit SPF on the subdomains that send mail.

Check your own domain

Run a free scan and get your grade with the exact records to fix.

Scan a domain

Related guides

Do Subdomains Need Their Own SPF Record?