Только начинаете с DMARC? Начните с основ →
Вы добавляете в запись SPF ещё одного поставщика. Изменение в DNS проходит, ни одно письмо не отскакивает. А через неделю сводные отчёты показывают, что SPF проваливается для почты из Google Workspace — отправителя, которого никто не трогал годами.
Запись не ошибочная. Она слишком дорогая. SPF ограничивает каждую проверку десятью DNS-запросами, и новый include довёл вашу запись до 11. Сверх лимита получатель прекращает проверку и возвращает permerror для каждого письма с домена, а не только для почты нового поставщика.
Что входит в лимит
RFC 7208, раздел 4.6.4 перечисляет всё, что расходует запрос: механизмы include, a, mx, ptr и exists и модификатор redirect. Реализации обязаны ограничивать их общее число десятью, а при превышении — возвращать permerror.
Чаще всего спотыкаются на трёх деталях:
- Вложенные запросы тоже входят в лимит.
include:стоит один запрос плюс каждый запрос внутри записи, на которую он ссылается, — на любую глубину. ip4,ip6иallзапросов не расходуют. При проверке они не обращаются к DNS.- У пустых запросов свой лимит — два. Сюда относится механизм, который не находит ни одной записи: например, include поставщика, который убрал свой SPF-хост. Третий такой запрос тоже даёт
permerror.
Сколько на самом деле стоит один include
Инструкции поставщиков говорят, какой include добавить. Сколько он стоит, там не пишут. Мы развернули распространённые include 14 октября 2026 года:
| Include | Запросов |
|---|---|
_spf.google.com (Google Workspace) |
1 |
spf.protection.outlook.com (Microsoft 365) |
1 |
mail.zendesk.com |
1 |
amazonses.com |
1 |
_spf.salesforce.com |
2 |
sendgrid.net |
2 |
mailgun.org |
5 |
email.freshdesk.com |
7 |
Крупнейшие провайдеры публикуют плоские списки диапазонов ip4: и ip6:, так что каждый стоит один запрос. Остальные вкладывают записи друг в друга. Include, который Freshdesk приводит в документации, ведёт к SendGrid и ещё к четырём региональным записям самого Freshdesk: семь запросов за одну строку вашей записи. Добавьте Google Workspace и Mailgun — и такой записи нужно уже 13:
v=spf1 include:_spf.google.com include:email.freshdesk.com include:mailgun.org ~all
Эти цифры меняются всякий раз, когда поставщик перестраивает свою запись, и об этом никто не предупреждает. Считайте таблицу снимком и проверяйте собственную запись. Надёжнее всего пройти дерево вручную: запросите запись, повторите то же для каждого include в ней и так до конца.
dig +short TXT email.freshdesk.com
Что permerror делает с DMARC
DMARC проходит, когда SPF или DKIM проходит и согласуется с доменом в поле From: (RFC 9989). permerror — не pass, поэтому, как только запись выходит за лимит, SPF ничего не даёт ни одному письму. Все отправители теперь держатся только на DKIM.
Почта от сервисов, которые подписывают её вашим доменом, продолжает проходить. Почта, которая держалась на SPF, проваливает DMARC: локальный почтовый релей, сканер, отправляющий от scans@, поставщик, для которого так и не настроили DKIM. При p=none этого никто не заметит. При p=quarantine или p=reject это потерянные письма.
Сводные отчёты покажут проблему раньше, чем кто-то пожалуется. Ищите в блоке auth_results вот это:
<spf>
<domain>example.com</domain>
<result>permerror</result>
</spf>
permerror на вашем собственном домене для всех источников указывает на саму запись: лимит запросов, синтаксическую ошибку или две записи SPF на одном имени — раздел 4.5 тоже считает это permerror. Остальные поля отчёта разбирает статья о сводных отчётах.
Сначала сократите запись, потом сворачивайте
Большинство записей, вышедших за лимит, тянут лишний балласт. Начните с этого: каждый шаг убирает запросы и не добавляет ничего, что придётся поддерживать.
Уберите include поставщиков, которыми больше не пользуетесь. Такой есть в каждой записи: маркетинговая платформа трёхлетней давности, служба поддержки, которую давно заменили. Сводные отчёты за 30 дней покажут, какие источники действительно отправляют почту. Include, диапазоны которого ни разу не встречаются среди источников, — кандидат на удаление.
Уберите include, которые никогда не проверяются. SPF проверяет домен конверта (MAIL FROM), а не видимый адрес From: (RFC 7208, раздел 2.4). Многие платформы отправляют почту с адресом возврата на собственном домене. Для такой почты получатель проверяет SPF поставщика, а ваш include даже не читает. В отчётах домен SPF у такого источника — домен поставщика, а не ваш. Эти письма проходят DMARC через согласованный DKIM или не проходят вовсе, так что include только тратит запросы.
Замените a, mx и ptr адресами. Для собственных серверов ip4: и ip6: бесплатны. ptr в записи быть не должно вовсе: раздел 5.5 прямо говорит, что его не следует публиковать. Механизм mx часто остаётся от типовой записи, которую сгенерировал DNS-хостинг. Если входящую почту обслуживает Google или Microsoft, исходящую уже авторизует их include, а mx тратит запрос на серверы, которые почту принимают, а не отправляют.
Вынесите крупного отправителя на отдельный поддомен. Большинство сервисов, которые отправляют почту, поддерживает собственный Return-Path — обычно это CNAME вроде bounce.example.com, указывающий на поставщика. SPF для такой почты проверяется на поддомене, с отдельным лимитом в 10 запросов, и ничего не отнимает у вашей основной записи. В режиме relaxed, который DMARC использует по умолчанию, bounce.example.com согласуется с example.com в поле From:. Это единственное исправление, которое заодно улучшает согласование; как оно работает, объясняет статья о согласовании DMARC.
Свёртка SPF и почему статическая копия устаревает
Свёртка (SPF flattening) заменяет каждый include: диапазонами ip4: и ip6:, в которые он разворачивается, и запросы на этих поставщиков падают до нуля. Но у неё четыре собственные проблемы.
Копия не следит за поставщиком. Когда провайдер добавляет диапазон, его собственная запись меняется в тот же день. Ваша свёрнутая копия — нет, и почта из нового диапазона проваливает SPF без единой ошибки. Свёрнутая вручную запись работает в день публикации и с тех пор только устаревает.
Макросы не сворачиваются. Salesforce публикует v=spf1 exists:%{i}._spf.mta.salesforce.com -all. Макрос %{i} подставляет IP-адрес, с которого пришло письмо, поэтому решение принимается для каждого письма отдельно, в момент запроса. Списка диапазонов, который можно скопировать, просто нет. Оставьте этот include как есть.
Размер. RFC 7208 советует держать ответ SPF в пределах 450 октетов, чтобы он помещался в UDP-пакет (раздел 3.4), а одна строка TXT вмещает не больше 255 символов (раздел 3.3). Одно только дерево Freshdesk разворачивается в десятки диапазонов. Свёрнутая запись реального домена в итоге раскладывается на несколько связанных записей на поддоменах, которые теперь поддерживаете вы.
Две записи. Если вставить свёрнутую запись рядом со старой, на одном имени окажутся две записи v=spf1 — а это отдельный permerror.
Свёртка безопасна, если её регулярно пересобирают и публикуют заново, как только поставщик меняет диапазоны. На тарифе Professional DDMARC делает это за вас: вы указываете свои источники почты, DDMARC разворачивает их, держит диапазоны актуальными, когда провайдеры их меняют, и отдаёт результат из своей зоны, так что ваша основная запись сводится к одному include. Каким бы инструментом вы ни сворачивали, проверьте, как он обрабатывает записи с макросами вроде Salesforce.
Порядок, в котором мы работаем
- Сначала снизьте TTL. Установите для записи SPF TTL 300 секунд — минимум за один старый TTL до изменения, обычно за сутки. Тогда резолверы быстро подхватят новую запись, а ошибку можно будет откатить за минуты. Когда отчёты станут чистыми, верните прежний TTL.
- Посчитайте. Разверните дерево include до конца и запишите оба итога: общее число запросов и число пустых.
- Составьте перечень. Возьмите сводные отчёты за 30 дней и выпишите каждый источник, который отправляет почту от вашего домена, с его доменом SPF и результатом.
- Сократите. Уберите мёртвые include, include, которые никогда не проверяются, и механизмы
a,mx,ptr, которые можно заменить адресами. - Вынесите. Переведите самых крупных отправителей на поддомен с собственным
Return-Path. - Сверните остальное — инструментом, который держит его актуальным.
- Считайте каждый новый include до публикации. Сделайте подсчёт запросов частью подключения нового поставщика. Большинство записей выходит за лимит по одному поставщику за раз.