Ошибка отправки email через SMTP в Django: разрыв соединения
При настройке отправки электронных писем в Django через SMTP-сервер (например, Яндекс) разработчики часто сталкиваются с ошибкой разрыва соединения. В логах появляется TimeoutError: [WinError 10060], а письма не доходят до получателя. В этой статье разберём причины проблемы и пошагово покажем, как её устранить.
Почему возникает ошибка TimeoutError при отправке email?
Ошибка WinError 10060 означает, что клиент (ваш Django-проект) не смог установить TCP-соединение с SMTP-сервером в течение заданного времени. Это может быть вызвано блокировкой порта фаерволом, неверными настройками SSL/TLS или неправильным хостом.
Основные причины разрыва соединения
- Неверный порт или протокол: для Yandex порт 465 требует SSL, а 587 - TLS. Если указан порт 465, но не включён
EMAIL_USE_SSL = True, соединение будет разорвано. - Блокировка антивирусом или брандмауэром: многие антивирусы (например, Kaspersky, Avast) или корпоративные файрволы блокируют исходящие SMTP-соединения.
- Проблемы с DNS: если хост
smtp.yandex.ruне резолвится, соединение не будет установлено. - Неверные учётные данные: пароль приложения для Яндекса должен быть сгенерирован специально для почтового клиента, а не обычный пароль от аккаунта.
Как исправить ошибку отправки писем в Django
Рассмотрим проверенные решения для настройки SMTP в Django, которые помогут устранить разрыв соединения.
1. Проверьте настройки порта и SSL
Убедитесь, что в settings.py указаны правильные параметры. Для Яндекса используйте один из двух вариантов:
- Порт 465 с SSL:
EMAIL_PORT = 465,EMAIL_USE_SSL = True,EMAIL_USE_TLS = False. - Порт 587 с TLS:
EMAIL_PORT = 587,EMAIL_USE_TLS = True,EMAIL_USE_SSL = False.
Не используйте оба флага одновременно - это вызовет конфликт.
2. Сгенерируйте пароль приложения для Яндекса
Яндекс требует специальный пароль для внешних приложений. Зайдите в настройки аккаунта → «Пароли приложений» → создайте пароль для почтового клиента. Используйте его в EMAIL_HOST_PASSWORD.
3. Отключите временно антивирус и брандмауэр
Для диагностики отключите антивирус (например, Kaspersky) и встроенный брандмауэр Windows. Если после этого письма отправляются - добавьте Django в исключения антивируса.
4. Проверьте доступность SMTP-сервера
Выполните в терминале команду telnet smtp.yandex.ru 465 (или 587). Если соединение не устанавливается - проблема на уровне сети или провайдера. Попробуйте использовать другой SMTP-сервер, например Gmail или Mailtrap для тестов.
Пример корректной конфигурации для Яндекс.Почты
Вот рабочий фрагмент settings.py для отправки через Yandex SMTP:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.yandex.ru'
EMAIL_PORT = 465
EMAIL_USE_SSL = True
EMAIL_HOST_USER = 'ваш-логин@yandex.ru'
EMAIL_HOST_PASSWORD = 'ваш-пароль-приложения'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USERПосле изменения настроек перезапустите сервер разработки и проверьте отправку через консоль Django: python manage.py shell → from django.core.mail import send_mail → send_mail('Тема', 'Текст', 'from@yandex.ru', ['to@example.com']).
Что делать, если ошибка остаётся?
Если проблема не решена, проверьте логи на стороне SMTP-сервера (для Яндекса - раздел «Безопасность» в аккаунте). Также попробуйте использовать EMAIL_USE_TLS = True с портом 587 - этот метод часто работает, когда SSL-соединение блокируется провайдером. Для отладки включите логирование Django SMTP, добавив в settings.py:
import logging
logging.basicConfig(level=logging.DEBUG)Это покажет детали рукопожатия с сервером и укажет на точную причину сбоя.