メールがメールサーバーを見つける仕組み
送信者
you@gmail.com
MX検索
誰が受け取る?
メールサーバー
優先度10が最初
受信トレイ
配信完了
優先度の数値が小さいものが優先され、大きいものはバックアップ
SPF's 10-Lookup Limit: What Counts and How to Stay Under It
A receiving mail server checks SPF by evaluating your record, and evaluating it costs DNS queries. To keep that cost bounded, RFC 7208 caps how many query-causing terms one check may evaluate. Cross the cap and the result is permerror, a permanent error that is not a pass. Checkers commonly report it as “too many DNS lookups”, and it usually surfaces right after another sending service is added to the record.
What the specification counts
Section 4.6.4 of RFC 7208 lists the terms that cause DNS queries: the include, a, mx, ptr and exists mechanisms and the redirect modifier. Implementations must limit the total of those terms to 10 during one evaluation and must return permerror if the limit is exceeded. The all, ip4 and ip6 mechanisms need no query and are not counted, and neither is the exp modifier, which is only fetched later, after a failure.
| Term | Counts toward 10? | Notes |
|---|---|---|
include | Yes | Plus every counted term inside the record it points to |
a | Yes | One lookup for the name |
mx | Yes | Separately limited to 10 address lookups; more gives permerror |
ptr | Yes | Discouraged: the RFC says it should not be published |
exists | Yes | One query |
redirect | Yes | Counts when it is reached (only if no mechanism matched, and never when the record contains all); the target is then evaluated with the same budget |
ip4, ip6 | No | The address is in the record itself |
all | No | Conventionally the last mechanism; anything after it is ignored |
exp | No | Fetched only after a failure, for the explanation string |
Two details matter. First, include does not copy another record into yours: only its result is used, and the RFC admits the name was poorly chosen. A -all inside an included record does not end the overall evaluation. Second, mechanisms are evaluated from left to right and processing stops at the first one that matches. The limit applies to terms actually evaluated during a check, not to the size of the record on paper.
Counting a record by hand
Consider a hypothetical record for a company that uses two mail platforms, a CRM, a help desk and its own mail server:
v=spf1 include:mailer-a.example include:mailer-b.example include:crm.example include:helpdesk.example mx a ~allSuppose the included records contain the terms below. They are invented for illustration, and real providers' records differ and change over time.
| Term evaluated | Lookups used so far |
|---|---|
include:mailer-a.example | 1 |
inside it: include:_nets.mailer-a.example | 2 |
include:mailer-b.example | 3 |
inside it: a | 4 |
inside it: mx | 5 |
include:crm.example | 6 |
inside it: include:spf1.crm.example | 7 |
inside it: include:spf2.crm.example | 8 |
include:helpdesk.example | 9 |
mx | 10 |
a | 11: over the limit, permerror |
Mail sent through the first platform matches early and passes. Mail from the server that only the last a authorizes needs an eleventh lookup, so the check returns permerror instead of a match. That asymmetry is why this fault looks intermittent: it depends on which sender's mail is being checked.
Other limits in the same specification
- Void lookups. A query that returns no records, or a name error, is a void lookup. RFC 7208 recommends limiting them to two, and exceeding the limit produces
permerror. Separately, aninclude:whose target has no SPF record, including a name that no longer exists, returnsnone, and the include mechanism turns that intopermerrorat once, so a stale include can break a record on its own. - Fan-out. An
mxmechanism may not trigger more than 10 address lookups. Forptr, names beyond the first 10 are ignored. - One record only. If a domain publishes more than one record whose version is exactly
v=spf1, the result ispermerror. - Size. The RFC advises keeping the published record small enough that the answer fits in 512 octets, so it travels in a single UDP packet without EDNS(0).
- Record type. SPF must be published as a TXT record. The dedicated SPF record type used in the experimental period has been discontinued.
- Time. Receivers should limit the time spent on one evaluation but allow at least 20 seconds. If that time limit is exceeded, the result should be
temperror, a temporary error, notpermerror.
How to get back under the limit
- Delete what you no longer use. A cancelled service still costs a lookup whenever evaluation reaches its
include. Removing dead includes is the cheapest fix. - Move senders to subdomains. Each name has its own record and its own budget of 10. Mail whose envelope sender is on
news.example.comis checked against that name's record, not the root's. Under relaxed alignment, DMARC still matches the subdomain to the organizational domain. - Replace
aandmxwith literals when the servers are yours and rarely change.ip4andip6cost nothing. - Flatten with care. Flattening swaps an
includefor the addresses it currently resolves to. It passes today and fails silently when the provider changes its ranges. - Drop
ptr. The RFC says it should not be published. Swappingredirectforincludesaves nothing, since both count one lookup. - Order by volume, but do not rely on it. Because evaluation stops at the first match, listing literals and your highest-volume senders first spends fewer lookups on most mail. That reduces how often the limit bites; it does not make an over-limit record valid, and it can hide the fault until a rarely used sender sends.
A permerror matters beyond SPF itself. DMARC (RFC 7489) passes when SPF or DKIM passes for an aligned domain, and permerror is not a pass, so SPF can no longer contribute. If DKIM is also missing or misaligned, the message fails DMARC. To see your own count, the SPF checker follows every include and redirect and counts the lookups across the whole tree against the limit of 10. That is a worst-case count of terms, not only the ones a given message would trigger. When you change the record, lower its TTL first so a mistake can be reverted quickly; see DNS TTL explained. For the wider picture, read SPF, DKIM and DMARC explained.
重要なポイント
Count terms, not characters: include, a, mx, ptr, exists and redirect each cost one lookup, nested ones included, and the eleventh makes the check return permerror.
Sources and further reading
- RFC 7208: Sender Policy Framework (SPF) for Authorizing Use of Domains in Email, Version 1 (Kitterman, 2014)
- RFC 7489: Domain-based Message Authentication, Reporting, and Conformance (DMARC) (Kucherawy and Zwicky, 2015)
ドメインの公開DNSアドレスを調べたい場合は、Domain IP Lookupツールをお試しください。
このテーマの無料ツール
よくある質問
関連記事
ほぼすべてのゾーンで出会うレコード
TXTレコードを解説:SPF、DKIM、DMARC
あなたのメールと迷惑メールフォルダーの間に立つ、3つのTXTレコード。それぞれの役割、構文の読み方、安全な導入の順序を解説します。
メールがメールサーバーを見つける仕組み
送信者
you@gmail.com
MX検索
誰が受け取る?
メールサーバー
優先度10が最初
受信トレイ
配信完了
優先度の数値が小さいものが優先され、大きいものはバックアップ
メールのDNSレコード:MX、SPF、DKIM、DMARC
メールが依存するDNSレコードの実践ガイドです。配送経路と認証がどう連携するのか、メール移行後に何を確認すべきかを、順を追って解説します。
メールがメールサーバーを見つける仕組み
送信者
you@gmail.com
MX検索
誰が受け取る?
メールサーバー
優先度10が最初
受信トレイ
配信完了
優先度の数値が小さいものが優先され、大きいものはバックアップ
MXレコードとは?メール配送の仕組みを解説
メールの届け先を決めるレコードです。優先度の数字の仕組み、null MXの意味、メッセージが気づかないうちに失われる間違いを解説します。