Битрикс: не отправляется почта с сайта
Когда сайт на «1С-Битрикс» показывает «Сообщение отправлено», а письма в почтовом ящике нет, начинать с настройки SMTP не стоит. Между формой и ящиком получателя есть несколько отдельных этапов: Битрикс должен создать почтовое событие, обработать его, сформировать письмо по шаблону, передать сообщение почтовому транспорту, а уже затем SMTP-сервер должен доставить его дальше.
Поэтому два внешне одинаковых случая могут иметь совершенно разные причины. В одном проекте заявка сохраняется, но почтовое событие вообще не создаётся. В другом события копятся в b_event, потому что cron не подхватывает очередь. В третьем Битрикс уже закончил свою работу, но удалённый почтовый сервер отвергает сообщение или принимает его, после чего письмо попадает в спам.
Диагностику лучше строить от последней точки, которая точно работает: Битрикс, очередь, почтовый шаблон, транспорт, SMTP, сервер получателя. Не меняйте одновременно cron, PHP, DNS и настройки почты. Иначе после первой же правки будет непонятно, где находилась исходная проблема.
Как понять, на каком этапе Битрикс теряет письмо
Сначала нужно определить, где обрывается цепочка отправки. Сам факт отсутствия письма во «Входящих» ещё ничего не говорит о состоянии SMTP: сообщение могло не выйти даже из почтовой подсистемы Битрикс.
Создайте одну контролируемую отправку. Подойдёт форма обратной связи, регистрация, уведомление о заказе или другой сценарий, который сейчас не работает. Используйте узнаваемый текст и запишите точное время. Не нажимайте кнопку десять раз подряд: один тест с известным временем намного проще сопоставить с b_event, PHP-логом и журналом MTA.
Для обычной отложенной отправки через CEvent::Send() или Bitrix\Main\Mail\Event::send() первым ориентиром будет событие и его обработка. Но здесь есть принципиальное исключение: CEvent::SendImmediate() и соответствующая немедленная отправка в D7 не используют обычную очередь так же, как Send(). Для CEvent::SendImmediate() отсутствие строки в b_event ожидаемо. В этом случае искать «потерянное событие» в таблице бессмысленно — нужно сразу идти к шаблону и почтовому транспорту.
| Симптом | Где искать проблему | Следующая проверка |
|---|---|---|
После Send() новой записи в b_event нет |
Компонент, обработчик, тип события, обработчики Битрикс | Проверить, выполняется ли код создания события |
Используется SendImmediate(), строки в b_event нет |
Это ожидаемо для немедленной отправки | Проверять шаблон и реальный транспорт |
Событие появилось, но остаётся с SUCCESS_EXEC=N |
Очередь, агенты, cron | Проверить автоматическую обработку |
SUCCESS_EXEC=0 |
Битрикс не нашёл подходящий почтовый шаблон | Проверить EVENT_NAME, сайт и активность шаблона |
| Битрикс обработал событие, но в MTA нет тестового письма | PHP, custom_mail(), локальный транспорт |
Определить фактический путь сообщения |
| SMTP возвращает отказ | Соединение, TLS, AUTH, sender или recipient | Разобрать полный SMTP-ответ |
| Удалённый MX принял сообщение | Дальнейшая доставка | Проверить bounce, Spam и аутентификацию домена |
Типичная диагностическая ошибка выглядит так: в форме нет события, а администратор уже меняет SPF. Это два разных уровня. Сначала найдите первый неподтверждённый этап.
Короткое правило: если не подтверждён предыдущий этап, следующий пока не чините.
Создаёт ли Битрикс почтовое событие после отправки формы
Если код использует обычную отправку через CEvent::Send() или Bitrix\Main\Mail\Event::send(), после теста нужно проверить, появилось ли событие. Если его нет, SMTP пока вообще ни при чём.
Форма может успешно сохранить данные в инфоблок, CRM или собственную таблицу и показать пользователю сообщение «Спасибо», хотя участок кода с почтовым вызовом не выполнился. Особенно часто это приходится проверять в кастомных компонентах, AJAX-обработчиках и формах, которые несколько раз дорабатывались.
Для диагностики удобно посмотреть последние записи b_event:
SELECT
ID,
EVENT_NAME,
DATE_INSERT,
DATE_EXEC,
SUCCESS_EXEC
FROM b_event
ORDER BY ID DESC
LIMIT 50;
Ищите строку примерно с тем же временем, когда была отправлена тестовая форма. EVENT_NAME должен соответствовать проверяемому сценарию. Если запись появилась, код как минимум дошёл до создания события.
Когда отсутствие строки в b_event нормально
Перед выводом «Битрикс не создаёт событие» посмотрите, какой метод вызывается в коде. CEvent::SendImmediate() отправляет письмо немедленно и не создаёт обычную запись в b_event. Это важное исключение.
То есть проверка должна выглядеть так:
CEvent::Send()илиEvent::send()— ищем событие и анализируем очередь;CEvent::SendImmediate()или немедленная отправка D7 — отсутствие строки вb_eventсамо по себе ошибкой не считается;- собственный
custom_mail()— сначала выясняем, что именно делает пользовательская функция.
События нет? Останавливаемся здесь. Сначала нужно доказать, что оно вообще должно было попасть в очередь.
Когда событие отменяет или меняет обработчик
В старых проектах с CEvent::Send() стоит проверить OnBeforeEventAdd. Этот обработчик вызывается перед добавлением почтового события в b_event, может изменить передаваемые поля, сайт и другие параметры, а при определённой логике обработчика добавление события может быть отменено.
Разработчик смотрит в компонент, видит корректный CEvent::Send() и делает вывод, что запись обязана появиться. Но между вызовом и таблицей может находиться пользовательский обработчик.
Ищите такую логику прежде всего в проектных файлах и собственных модулях. Например:
grep -R "OnBeforeEventAdd" \
/path/to/site/local \
/path/to/site/bitrix/php_interface \
2>/dev/null
Проверяйте также PHP-лог. Если обработчик формы падает после сохранения заявки, интерфейс может сообщить об успешной операции, а код почтовой отправки до выполнения не дойдёт.
Сравните рабочий и нерабочий сценарии. Регистрация создаёт событие, а форма обратной связи нет? Значит, общая почтовая инфраструктура уже не первый подозреваемый — различие нужно искать в конкретном компоненте, EVENT_NAME, обработчиках и передаваемых полях.
Что означают статусы почтовых событий в b_event
SUCCESS_EXEC — одна из самых полезных точек диагностики обычной очереди Битрикс. Значение показывает не то, увидел ли пользователь письмо во «Входящих», а результат обработки события почтовой системой Битрикс.
| SUCCESS_EXEC | Что означает | Что проверять дальше |
|---|---|---|
N |
Почтовое событие ещё не обработано | Агенты, cron, CEvent::CheckEvents(), механизм запуска очереди |
Y |
Все письма по найденным шаблонам Битрикс обработал успешно | Почтовый транспорт, MTA и фактическую доставку |
F |
Отправить письма по шаблонам не удалось | Транспорт, mail(), custom_mail(), SMTP и логи |
P |
Часть писем отправлена успешно, часть — нет | Несколько шаблонов, разные получатели и результаты каждого сообщения |
0 |
Подходящие почтовые шаблоны не найдены | EVENT_NAME, привязку к сайту, активность и условия выбора шаблона |
N и 0 — совершенно разные проблемы. При N событие ещё ждёт обработки. При 0 обработка уже состоялась, но Битрикс не нашёл письмо, которое можно было бы сформировать.
То же самое с Y. Оно не означает «письмо доставлено в Gmail». Оно означает, что этап обработки Битрикс прошёл успешно. Дальше сообщение ещё может застрять в локальном MTA, получить 4xx от удалённого сервера, вернуться с 5xx или попасть в спам.
Статус P особенно полезен, если к одному EVENT_NAME привязано несколько почтовых шаблонов. Один адресат может получить письмо, второй — нет. В таком случае «SMTP иногда работает» — слишком грубое описание. Нужно смотреть каждый сформированный шаблон и получателя.
Если в b_event за последние часы все новые строки стоят с N, это системный сценарий. Если N только у одного конкретного события, а остальные переходят в Y, искать глобальную поломку cron уже менее логично.
Есть Y? Очередь Битрикс уже прошли. Не возвращайтесь к cron без нового признака проблемы.
Почему почтовое событие Битрикс остаётся в очереди
Если новые записи появляются в b_event и остаются с SUCCESS_EXEC=N, проблема находится в обработке очереди. SMTP может быть полностью исправен: письмо до него ещё не дошло.
Письма начинают уходить только после открытия страниц сайта
Такой симптом указывает на зависимость фоновой обработки от хитов. Пока по сайту идут запросы, события разбираются; на малопосещаемом проекте очередь стоит.
Сделайте контролируемый тест: создайте событие, запишите его ID и DATE_INSERT, не открывайте публичные страницы несколько минут и снова проверьте строку. Затем выполните обычный запрос к сайту и посмотрите, изменились ли DATE_EXEC и SUCCESS_EXEC.
Если событие обрабатывается сразу после хита, это хороший повод проверить, как именно в проекте настроены агенты и перенесена ли почтовая обработка на cron.
После переноса агентов на cron события продолжают копиться
Типичная картина после миграции или оптимизации: сайт открывается, формы сохраняются, но cron на новом сервере не запускает нужный PHP-скрипт. В b_event тем временем растёт хвост из N.
Проверять нужно не наличие строки в crontab, а факт выполнения команды. На системе с systemd можно посмотреть сообщения cron за нужный период:
journalctl --since "30 minutes ago" | grep -Ei "cron|crond"
Сам по себе такой вывод ещё не доказывает, что отработал нужный PHP-файл. Сопоставьте три времени:
DATE_INSERTтестового события;- время запуска нужной cron-задачи;
DATE_EXECсобытия после обработки.
Отдельно проверьте PHP внутри cron. Команда php из окружения cron может указывать не на тот бинарник, которым работает сайт. На сервере с несколькими версиями PHP это вполне реальный сценарий.
which php
php -v
php --ini
Если в crontab прописан абсолютный путь, проверяйте именно его, а не системный PHP из интерактивного SSH-сеанса.
Что доказывает ручной CEvent::CheckEvents()
CEvent::CheckEvents() обрабатывает необработанные почтовые события. Ручной запуск уместен как разовый диагностический тест, но не как постоянный способ заставлять сайт отправлять письма.
Есть две разные развилки:
| Результат проверки | Что это означает | Куда смотреть дальше |
|---|---|---|
Событие было N, после ручной обработки перешло в Y/F/P/0 |
Механизм обработки события запускается вручную | Проверять автоматический запуск, cron и окружение |
Событие остаётся N даже после корректного тестового запуска |
Проблема не сводится к расписанию cron | Проверить способ вызова, PHP-ошибки и конфигурацию проекта |
Если очередь разобралась после ручного запуска, круг уже сильно сузился. После исправления создайте новое событие и убедитесь, что оно меняет статус автоматически. Старые записи сами по себе не доказывают, что проблема устранена.
Может ли проблема быть в почтовом шаблоне Битрикс
Если одни уведомления Битрикс работают, а письма только из конкретной формы, заказа или регистрации не приходят, сначала сравните почтовые события и шаблоны. Общий SMTP при таком сценарии уже доказал хотя бы базовую работоспособность.
В административной части проверьте:
- активен ли нужный шаблон;
- совпадает ли его
EVENT_NAMEс создаваемым событием; - к какому сайту привязан шаблон;
- что попадает в поле получателя;
- какой адрес формируется в
From; - не остаётся ли один из макросов пустым;
- сколько активных шаблонов связано с одним событием.
Если в b_event у тестового события стоит SUCCESS_EXEC=0, это сильный диагностический признак: Битрикс обработал событие, но подходящих почтовых шаблонов не нашёл. В такой ситуации проверять firewall и SMTP-пароль рано.
SUCCESS_EXEC=P указывает на другой сценарий: часть сообщений прошла, часть нет. Обычно здесь нужно смотреть не «почту Битрикс в целом», а конкретные шаблоны, сайты и адресатов.
Почему настройки шаблона выглядят правильно, а письмо формируется иначе
Сохранённый в административной панели шаблон — не всегда последняя точка, где меняются данные письма. Перед фактической отправкой в проекте могут работать пользовательские обработчики.
OnBeforeEventSend вызывается перед отправкой сообщения и позволяет проектному коду вмешиваться в поля события и данные шаблона. Поэтому в админке To и From могут выглядеть корректно, а фактическое письмо уходит уже с изменёнными значениями.
Ищите обработчики:
grep -R "OnBeforeEventSend" \
/path/to/site/local \
/path/to/site/bitrix/php_interface \
2>/dev/null
Для старого CEvent::Send() отдельно проверяйте OnBeforeEventAdd: он работает ещё на этапе добавления события.
ONLY_EMAIL: письма уходят, но не тем получателям
В Битрикс существует константа ONLY_EMAIL, которая может перенаправлять исходящие письма на заданный адрес или группу адресов. Для тестового или staging-окружения это удобно, но после переноса такой параметр легко забыть.
Получается странный симптом: события обрабатываются, транспорт работает, ошибок нет, но реальные пользователи ничего не получают. Проверяйте, не определена ли эта константа в проектной конфигурации:
grep -R "ONLY_EMAIL" \
/path/to/site/local \
/path/to/site/bitrix/php_interface \
2>/dev/null
Также проверьте custom_mail(). Если проект переопределяет стандартный способ отправки, именно эта функция может менять транспорт, заголовки, получателя или полностью перехватывать письмо.
Если регистрация шлёт письма, а форма обратной связи нет, SMTP уже не главный подозреваемый. Сравнивайте два события по EVENT_NAME, сайту, шаблону и фактическим полям.
Как проверить, передаёт ли Битрикс письмо PHP или SMTP
После обработки события нужно определить фактический транспорт. Сайт может использовать стандартную mail(), sendmail-совместимый механизм, msmtp, локальный MTA, внешний SMTP или собственную custom_mail().
Вызов CEvent::Send() сам по себе не означает, что Битрикс в эту секунду открыл SMTP-соединение. Сначала событие обрабатывается на уровне CMS, затем сообщение передаётся дальше согласно конфигурации проекта.
Проверьте sendmail_path:
php -i | grep -i sendmail_path
Но это вывод CLI PHP. Если сайт работает через PHP-FPM, у него может быть другой php.ini. CLI отработал? Этого пока недостаточно.
Если используется пользовательская функция, найдите её:
grep -R "function custom_mail" /path/to/site 2>/dev/null
Что искать в журнале MTA
Привяжите поиск к времени тестового события. Если известны ID и DATE_EXEC в Битрикс, смотрите MTA именно вокруг этого timestamp. Формат Postfix, Exim и msmtp различается, но интересуют одни и те же вещи: время, отправитель или получатель, идентификатор сообщения и финальный статус.
Условный фрагмент Postfix, когда локальный MTA принял письмо:
postfix/qmgr[2148]: 3F4A812345: from=<site@example.com>, size=2841, nrcpt=1 (queue active)
Здесь появился queue ID 3F4A812345. Это уже доказательство, что сообщение дошло до Postfix. Дальше ищите строки с тем же ID.
Успешная передача может выглядеть так:
postfix/smtp[2191]: 3F4A812345: to=<admin@example.net>,
relay=mx.example.net[203.0.113.20]:25,
dsn=2.0.0, status=sent (250 2.0.0 Ok: queued)
А временная проблема соединения — так:
postfix/smtp[2191]: 3F4A812345: to=<admin@example.net>,
relay=none, status=deferred
(connect to mx.example.net[203.0.113.20]:25: Connection timed out)
Строки приведены как пример структуры лога, а не как единственно возможный формат.
| Что видно в логе | Что это доказывает | Куда идти дальше |
|---|---|---|
| Записи о тестовом письме нет | До проверяемого MTA сообщение не дошло | Битрикс, PHP, custom_mail(), sendmail_path |
| Появился queue ID | MTA принял письмо | Искать дальнейшие строки по тому же ID |
status=sent и ответ 2xx |
Следующий SMTP-сервер принял сообщение | Доставляемость, Spam, bounce, DNS-аутентификация |
deferred или ответ 4xx |
Временная проблема, письмо может остаться в очереди | Причина defer, удалённый сервер, сеть |
bounced или окончательный 5xx |
Удалённый сервер окончательно отверг сообщение | Разбирать полный текст ответа |
Если в b_event уже Y, а в почтовом логе за ту же секунду нет даже попытки, граница проблемы находится между Битрикс/PHP и MTA. Если queue ID есть — двигаемся дальше по нему.
Почему SMTP в Битрикс не подключается или не принимает письмо
SMTP-ошибку нужно разбирать по этапу: TCP-соединение, TLS, авторизация, отправитель, получатель, передача сообщения. Полный ответ сервера ценнее формулировки «SMTP не работает».
SMTP connection refused или timeout
Connection refused и timeout появляются до нормальной отправки письма. Почтовый шаблон Битрикс здесь пока не главный подозреваемый.
Проверьте TCP-соединение:
nc -vz smtp.example.com 587
Если соединение не устанавливается, проверяйте hostname, DNS, порт, firewall и ограничения исходящего трафика. Один timeout ещё не доказывает, что провайдер блокирует порт: неверный адрес SMTP даст похожий симптом.
SMTP Authentication failed
Если сервер отвечает ошибкой AUTH, соединение с ним уже состоялось. Проверяйте логин, пароль, пароль приложения, разрешение SMTP-аутентификации в Битрикс и требования конкретного почтового сервиса.
Пример диагностически полезного сообщения:
535 5.7.8 Authentication credentials invalid
Текст у разных серверов отличается. Не диагностируйте только по номеру — сохраняйте ответ целиком.
Ошибка TLS или сертификата
При TLS-ошибке проверяйте hostname, режим шифрования, сертификат и доверенные CA. Отключение проверки сертификата может скрыть симптом, но не устраняет причину.
openssl s_client \
-starttls smtp \
-connect smtp.example.com:587 \
-servername smtp.example.com
Смотрите, установилась ли TLS-сессия и соответствует ли сертификат имени SMTP-сервера.
Как читать классы SMTP-кодов
Первая цифра ответа быстро показывает направление диагностики:
2xx— команда принята;4xx— временный отказ, повторная доставка может быть возможна;5xx— постоянный отказ для текущей попытки.
Например, 421 или 451 часто относятся к временным проблемам, 535 встречается при ошибках аутентификации, а 550 и 553 могут относиться к получателю, отправителю или политике сервера. Но код без текста ответа — только половина диагноза.
| Симптом | Вероятный уровень | Что проверять |
|---|---|---|
Connection refused |
TCP/сервис | Hostname, порт, работа SMTP-сервиса, firewall |
Timeout |
Сеть | Маршрут, firewall, ограничения провайдера, DNS |
TLS handshake failed |
TLS | Сертификат, CA, hostname, режим шифрования |
535 / Authentication failed |
AUTH | Логин, пароль, пароль приложения, политика сервиса |
| Sender rejected | MAIL FROM | Адрес отправителя и разрешение отправлять от его имени |
| Recipient rejected | RCPT TO | Получателя и полный ответ удалённого сервера |
250 после передачи сообщения |
SMTP принял письмо | Дальнейшую доставку, а не очередь Битрикс |
Сохраняйте полный SMTP-ответ и время теста. Эти две вещи обычно сразу сокращают половину лишних проверок.
Что проверить на хостинге или VPS, если Битрикс не отправляет почту
На сервере проверяйте не абстрактную «работу PHP», а путь конкретного события Битрикс. Свяжите EVENT_ID, DATE_EXEC и запись MTA по одному времени.
Например, событие ID 12345 создано в 14:32:10 и перешло в Y в 14:32:11. Теперь в mail log нужно искать отправку около 14:32:11. Записи нет — до MTA письмо не дошло. Запись есть — Битрикс и PHP уже можно отодвинуть на второй план.
Сравните PHP CLI и PHP сайта
На сервере может одновременно работать несколько версий PHP. Команды из SSH показывают только CLI:
php -v
php --ini
php -i | grep -i sendmail_path
Для веб-PHP сравните минимум:
- версию PHP;
- SAPI;
- Loaded Configuration File;
sendmail_path;- пользователя процесса;
- окружение, если
custom_mail()вызывает внешнюю команду.
CLI отработал, а сайт нет — это не противоречие. Они могут читать разные php.ini.
Проверьте доступность внешнего SMTP с сервера сайта
getent hosts smtp.example.com
nc -vz smtp.example.com 587
Если DNS разрешается, но TCP не открывается, проверяйте firewall и маршрут. Если hostname вообще не разрешается — SMTP-пароль пока не имеет значения.
Проверьте локальный почтовый транспорт
Если PHP использует sendmail_path, убедитесь, что указанный бинарник существует и доступен пользователю веб-сервера. Для msmtp проверьте его конфигурацию и лог, для локального Postfix/Exim — соответствующий mail log или journal.
На VPS дополнительно смотрят:
- права на конфигурационные файлы;
- исходящие SMTP-порты;
- локальный firewall;
- DNS resolver;
- SELinux/AppArmor, если они действительно активны и ограничивают нужный процесс;
- перезапуск сервисов после изменения конфигурации.
Если b_event уже показывает Y, а в MTA пусто, не нужно заново чинить cron. Узкое место уже ниже.
Почему неправильные From, To и Reply-To ломают отправку
Если SMTP подключается, но часть писем отвергается или сообщения приходят с неожиданным отправителем, проверьте фактические From, To и Reply-To после подстановки макросов.
Частый сценарий — контактная форма берёт email посетителя и подставляет его прямо в From. Сайт example.com в результате пытается отправить через свою почтовую инфраструктуру письмо как будто от user@gmail.com. SMTP-сервис может запретить такую отправку, а DMARC домена пользователя дополнительно усложнит доставку.
Для формы обратной связи предсказуемее такая схема:
From: Website <site@example.com>
To: manager@example.com
Reply-To: visitor@example.net
Сайт отправляет письмо от собственного домена, а менеджер при ответе получает адрес посетителя из Reply-To.
Смотрите также envelope sender. Видимый From и SMTP-отправитель — не всегда одно и то же. При проблеме сервер может вернуть, например:
Sender address rejected
или сообщение о том, что текущая учётная запись не имеет права отправлять от указанного адреса. Формулировка зависит от SMTP-сервера.
Для To проверяйте уже итоговое значение. В шаблоне может стоять #EMAIL_TO#, а событие передаёт пустое поле, старый адрес после миграции или строку в неожиданном формате.
Быстрый тест: временно используйте один известный внешний адрес получателя и подтверждённый адрес собственного домена в качестве отправителя. Если сообщение проходит, возвращайте исходные значения по одному.
Email посетителя формы обычно нужен в Reply-To, а не в From.
Почему Битрикс сообщает об отправке, но письмо не приходит
После успешной обработки события начинается отдельная почтовая цепочка. SUCCESS_EXEC=Y не гарантирует Inbox, а даже 250 OK от удалённого SMTP-сервера означает только то, что следующая сторона приняла сообщение.
SMTP отверг письмо сразу
Если удалённый сервер ответил 5xx во время SMTP-сессии, причина обычно видна прямо в логе. Например:
550 5.1.1 Recipient address rejected: User unknown
В этом сценарии не нужно возвращаться к шаблону Битрикс, если адрес сформирован правильно. Разбирайте конкретный отказ удалённого сервера: несуществующий ящик, sender policy, блокировку или другую причину из ответа.
SMTP принял письмо, но позже пришёл bounce
Иногда первый сервер принимает сообщение, а ошибка возникает на следующем этапе. Тогда отправителю приходит bounce. В нём могут быть указаны переполненный ящик, временная недоступность, policy rejection или другая причина, которой не было в первоначальной SMTP-сессии сайта.
Проверяйте не только папку «Входящие», но и адрес возврата. Если bounce есть, это один из самых ценных диагностических документов: в нём уже содержится ответ удалённой стороны.
Сервер получателя принял письмо, но пользователь его не видит
Бывает и так: в MTA есть status=sent, удалённый MX ответил 250, а пользователь продолжает обновлять «Входящие». На этом этапе Битрикс уже свою часть работы сделал.
Письмо может оказаться:
- в Spam/Junk;
- в отдельной категории или вкладке;
- в корпоративном карантине;
- под пользовательским фильтром;
- под внутренним антиспамом принимающей системы.
| Что произошло | Что видно в логе | Следующий шаг |
|---|---|---|
| Удалённый SMTP сразу отказал | 5xx, bounced/rejected |
Разобрать полный ответ сервера |
| Сервер временно отложил письмо | 4xx, deferred |
Проверить очередь MTA и повторные попытки |
| Удалённый MX принял сообщение | 250, sent |
Spam, bounce, аутентификация, фильтры получателя |
Если письма с сайта Битрикс не приходят только на один домен, отправьте один и тот же тест на два независимых почтовых сервиса. Один принимает, другой стабильно отказывает? Очередь Битрикс здесь уже не виновата.
Как SPF, DKIM и DMARC влияют на письма с сайта Битрикс
SPF, DKIM и DMARC нужно проверять после подтверждения, что сообщение покинуло Битрикс и действительно отправляется наружу. Эти DNS-механизмы не исправят SUCCESS_EXEC=N и не запустят cron.
SPF определяет разрешённые источники отправки домена. После перехода с локального MTA на внешний SMTP старый SPF может больше не соответствовать фактическому отправителю.
dig TXT example.com
Проверьте, нет ли нескольких отдельных записей v=spf1. Добавлять вторую SPF-запись рядом с первой обычно не нужно — источники объединяют в одну корректную политику.
DKIM подтверждает подпись письма. При внешнем SMTP селектор и DNS-запись обычно задаются настройками конкретного почтового сервиса.
dig TXT selector._domainkey.example.com
DMARC проверяет, согласуются ли результаты аутентификации с доменом в видимом From. Именно здесь хорошо видна проблема, когда контактная форма подставляет чужой адрес в поле отправителя.
При собственной отправке с VPS проверьте PTR/rDNS:
dig -x 203.0.113.10
| Механизм | Что проверяет | Чего не исправляет |
|---|---|---|
| SPF | Разрешён ли источник отправки | Очередь Битрикс |
| DKIM | Корректна ли подпись домена | SMTP timeout |
| DMARC | Согласованы ли домены и политика | Неверный почтовый шаблон |
| PTR/rDNS | Обратное имя IP собственного MTA | Ошибка SMTP AUTH |
Что смотреть в Authentication-Results
Если письмо дошло хотя бы в спам, откройте полные заголовки и найдите Authentication-Results. Нормальный фрагмент может содержать:
Authentication-Results:
spf=pass
dkim=pass
dmarc=pass
Проблемный вариант может выглядеть иначе:
Authentication-Results:
spf=pass
dkim=none
dmarc=fail
Второй пример не означает автоматически, что именно DMARC был единственной причиной попадания в спам, но он даёт конкретный сигнал для проверки: SPF прошёл, DKIM-подписи нет, а DMARC не получил требуемого согласования.
Правильные SPF, DKIM и DMARC не гарантируют Inbox. Они закрывают только часть цепочки доставляемости.
Что проверить, если письма перестали отправляться после переноса Битрикс
После миграции в первую очередь сравнивайте то, что находилось вне базы данных. Файлы и дамп MySQL могут переехать корректно, а системный cron, MTA, sendmail_path, firewall и PTR останутся на старом сервере.
Типичная картина: сайт открывается, заявки сохраняются, события появляются в b_event, но все новые строки остаются N. Причина оказывается не в почтовом шаблоне, а в cron, который на новый VPS просто не перенесли.
| Что сравнить | Старый сервер | Новый сервер | Почему это важно |
|---|---|---|---|
| PHP и SAPI | Версия и способ запуска | Версия и способ запуска | Может отличаться окружение сайта |
php.ini |
Loaded Configuration File | Loaded Configuration File | Настройки почты могут различаться |
sendmail_path |
Старое значение | Новое значение | Определяет локальный транспорт PHP |
| cron | Команда, пользователь, расписание | Команда, пользователь, расписание | Влияет на обработку очереди |
| SMTP host/port | Фактические значения | Фактические значения | Проверяет внешний транспорт |
| MTA / msmtp | Что было установлено | Что установлено сейчас | Системный транспорт не переносится с БД |
| Исходящий IP | Старый IP | Новый IP | Может влиять на SMTP и репутацию |
| PTR/rDNS | Старая запись | Новая запись | Критично при собственной отправке |
custom_mail() |
Старая реализация | Текущая реализация | Может зависеть от путей и окружения |
Проверьте cron:
crontab -l
Но помните: нужная задача может принадлежать другому системному пользователю. Кроме того, строка php script.php на новом сервере может запустить другой PHP, чем раньше.
Если изменился исходящий IP, проверьте внешний SMTP. Он может иметь ограничения по адресу источника. При собственной отправке дополнительно проверяются PTR и репутация нового IP.
Файлы и БД переехали. Системный cron и MTA — нет. Именно с этого различия и стоит начинать миграционную диагностику.
Как провести тест почты Битрикс так, чтобы результат действительно что-то доказывал
Корректный тест идёт от CMS к получателю по одной цепочке. Каждый следующий шаг имеет смысл только после подтверждения предыдущего.
-
Создайте одну тестовую отправку.
Запишите время, адрес получателя и узнаваемый текст.
-
Определите способ вызова почты.
Send()— ищем событие в очереди.SendImmediate()— отсутствие записиb_eventсамо по себе нормально. -
Для очереди проверьте SUCCESS_EXEC.
N,Y,F,Pи0ведут в разные ветки диагностики. -
Проверьте шаблон и итоговые адреса.
Убедитесь, что выбран правильный шаблон и макросы не дают пустые или чужие значения.
-
Определите реальный транспорт.
mail(), sendmail,msmtp, локальный MTA, внешний SMTP илиcustom_mail(). -
Привяжите тест к почтовому логу.
Ищите сообщение по времени, получателю и queue ID.
-
Разберите SMTP-результат.
4xx— временная проблема,5xx— отказ,2xx— сервер принял команду. -
После успешной передачи проверьте доставляемость.
Bounce, Spam, SPF, DKIM, DMARC и фильтры принимающей стороны.
1. Какой метод отправки использует Битрикс?
2. Если это очередь — событие появилось?
3. Какой SUCCESS_EXEC?
4. Выбран правильный шаблон и получатель?
5. Сообщение дошло до PHP/MTA?
6. SMTP принял его?
7. Удалённый MX принял письмо?
8. Что произошло после приёма: Inbox, Spam, bounce?
Останавливайтесь на первом неподтверждённом этапе. События нет — не трогаем DNS. Есть Y и queue ID — cron уже не трогаем. Есть 250 OK от удалённого MX — Битрикс здесь больше не чинят.
- Сделать одну контролируемую отправку и записать время.
- Определить
Send(),SendImmediate()или собственный транспорт. - Для очереди найти
EVENT_NAME, ID иSUCCESS_EXEC. - При
Nпроверить cron и обработку очереди. - При
0проверить почтовый шаблон и привязку к сайту. - При
Pпроверить все шаблоны и получателей события. - Проверить
From,To,Reply-To,ONLY_EMAILи пользовательские обработчики. - Определить реальный транспорт и
sendmail_path. - Сопоставить событие с MTA-логом по времени.
- При отсутствии соединения проверить DNS, host, port и firewall.
- При SMTP-ошибке сохранить полный ответ сервера.
- После
2xxперейти к доставляемости. - Проверить bounce и Spam/Junk.
- Проверить SPF, DKIM, DMARC и PTR там, где они применимы.
- После исправления создать новое тестовое сообщение и пройти цепочку ещё раз.
Что собрать перед обращением в поддержку хостинга или разработчику
Если проблема осталась, перед обращением в поддержку зафиксируйте конкретную тестовую отправку и уже проверенные этапы. Сообщение «Битрикс не шлёт почту» почти ничего не говорит о точке отказа.
Передайте:
- точное время теста;
- адрес отправителя и получателя;
- используемый метод:
Send(),SendImmediate()или другой; EVENT_NAMEи ID события, если очередь используется;SUCCESS_EXECиDATE_EXEC;- какой транспорт используется после Битрикс;
- hostname и порт SMTP без пароля;
- полный текст SMTP-ошибки;
- queue ID или несколько строк MTA-лога вокруг теста;
- работают ли другие почтовые события;
- возникла ли проблема после миграции, обновления PHP или изменения cron;
- получает ли то же письмо другой внешний почтовый домен.
Пароли SMTP, приватные ключи и другие секреты в обычный тикет отправлять не нужно.
Хорошее техническое описание выглядит так: «В 14:32 создано событие TEST_FORM, ID 12345. В b_event оно остаётся SUCCESS_EXEC=N, другие новые события имеют тот же статус». Здесь сразу проверяется очередь и cron.
Другой сценарий: «Событие ID 12345 перешло в Y в 14:32:11. В Postfix появился queue ID 3F4A812345, удалённый сервер вернул 535 Authentication failed». Возвращаться к форме и шаблону уже незачем.
И третий: «Удалённый MX ответил 250, но письма нет во входящих». Тогда дальнейшая проверка — bounce, Spam, заголовки, SPF, DKIM, DMARC и политика получателя.
После исправления повторите тест новым сообщением. Исправленной можно считать не старую строку в таблице, а новую отправку, которая проходит всю цепочку без ручного вмешательства.
WordPress хостинг

