ERR_SSL_PROTOCOL_ERROR: причины и решения

10 минут чтения
Средний рейтинг статьи — 4.8

Ошибка ERR_SSL_PROTOCOL_ERROR появляется, когда браузер не смог установить защищённое соединение с сайтом по HTTPS. Чаще всего её видят в Chrome и браузерах на Chromium: Edge, Opera, Яндекс Браузере. Иногда её ищут просто как err ssl protocol error, но суть одна: TLS-соединение обрывается раньше, чем браузер получает нормальный HTTP-ответ.

Сложность в том, что сообщение слишком общее. Причина может быть на стороне пользователя: неверное время, устаревший браузер, антивирус с HTTPS-сканированием, сломанный кэш SSL. Но для владельца сайта и DevOps-инженера чаще важнее серверные причины: неправильный сертификат, несовместимые версии TLS, ошибка SNI, некорректная настройка Nginx, CDN или балансировщика.

Разберём, что означает ERR_SSL_PROTOCOL_ERROR, как быстро понять, где проблема, и какие шаги помогают исправить её без гадания.

Что означает ERR_SSL_PROTOCOL_ERROR

Когда пользователь открывает https://example.com, браузер сначала устанавливает TCP-соединение с сервером, обычно на порт 443. Затем начинается TLS-рукопожатие: клиент и сервер договариваются о версии TLS, наборе шифров, проверяют сертификат и только после этого переходят к HTTP.

ERR_SSL_PROTOCOL_ERROR означает, что этот процесс сломался на уровне SSL/TLS-протокола. Браузер не получил корректное защищённое соединение и не может показать страницу.

Важно отличать эту ошибку от похожих:

  • NET::ERR_CERT_DATE_INVALID — сертификат просрочен или ещё не начал действовать.
  • NET::ERR_CERT_AUTHORITY_INVALID — сертификат выпущен недоверенным центром.
  • ERR_CONNECTION_REFUSED — порт закрыт или сервер отклонил соединение.
  • ERR_CONNECTION_TIMED_OUT — соединение не установилось за отведённое время.
  • 502, 503, 504 — HTTP-ошибки, которые возникают уже после успешного соединения с промежуточным сервером.

При ERR_SSL_PROTOCOL_ERROR браузер часто не может показать точную причину, потому что TLS-диалог оборвался слишком рано. Сервер мог отправить не TLS-ответ на HTTPS-порт, закрыть соединение, выбрать неподдерживаемый протокол или вернуть сертификат, который не подходит для имени хоста.

Если нужно освежить базу, полезно отдельно разобрать, как работает HTTPS, SSL, TLS и сертификаты. Это помогает быстрее понимать, на каком этапе искать сбой.

Как быстро понять: проблема у пользователя или у сайта

Перед исправлениями нужно определить масштаб. Один пользователь видит ошибку или сайт недоступен для всех? От этого зависит план действий.

1) Проверьте сайт из другой сети — откройте домен с мобильного интернета, через другой провайдер или с удалённого сервера. Если ошибка повторяется везде, вероятнее всего проблема на стороне сайта, CDN, DNS или хостинга. Если только в одной сети — смотрите прокси, корпоративный фильтр, антивирус, DNS-подмену.

2) Откройте сайт в другом браузере — если Chrome показывает ERR_SSL_PROTOCOL_ERROR, а Firefox открывает сайт нормально, возможна проблема в кэше браузера, расширениях, политике HSTS или поддержке конкретных TLS-настроек. Если все браузеры падают одинаково, причина чаще серверная.

3) Проверьте HTTP и HTTPS отдельно — откройте http://example.com и https://example.com. Если HTTP работает, а HTTPS нет, зона поиска сужается до TLS, сертификата, порта 443, reverse proxy или CDN. Если не работает ничего, начните с DNS, сети и веб-сервера.

4) Используйте внешний мониторинг — если сайт важен для бизнеса, лучше не узнавать о таких ошибках от пользователей. Сервис мониторинга доступности вроде Statuser проверяет сайт с заданным интервалом и присылает уведомление о сбое. Это особенно полезно для HTTPS-проблем: сертификат мог обновиться неправильно, CDN мог сменить режим SSL, а ошибка проявится сразу у всех клиентов.

5) Посмотрите, воспроизводится ли ошибка по IP — открывать HTTPS по IP обычно бессмысленно для публичных сайтов, потому что сертификат выпускается на домен. Но команда с указанием SNI через openssl или curl покажет, какой сертификат реально отдаёт сервер для нужного имени.

Частые причины на стороне пользователя

Если ошибка появляется только на одном устройстве, начните с локальной диагностики. Это быстрее, чем искать несуществующую проблему в Nginx.

1) Неверные дата и время — сертификаты имеют период действия: Not Before и Not After. Если системное время ушло далеко назад или вперёд, браузер может отклонить TLS-соединение. Включите автоматическую синхронизацию времени через NTP и перезапустите браузер.

2) Устаревший браузер или ОС — старые клиенты могут не поддерживать актуальные версии TLS, современные шифры или корневые сертификаты. Особенно часто это встречается на старых Android-устройствах, Windows без обновлений, встроенных браузерах и старых корпоративных образах.

3) Антивирус проверяет HTTPS-трафик — некоторые антивирусы и корпоративные агенты подменяют сертификаты, чтобы сканировать зашифрованный трафик. Если их локальный корневой сертификат установлен неправильно или модуль работает с ошибками, Chrome может показать ERR_SSL_PROTOCOL_ERROR. Для проверки временно отключите HTTPS-сканирование или откройте сайт с другого устройства в той же сети.

4) VPN, прокси или корпоративный фильтр — промежуточный узел может блокировать TLS, ломать SNI, подменять сертификат или не поддерживать нужные параметры соединения. Отключите VPN, смените сеть, проверьте системные настройки прокси.

5) Повреждённый SSL-кэш браузера — иногда помогает очистка кэша и cookies для сайта, сброс сетевых настроек Chrome или запуск в режиме инкогнито без расширений. В Windows дополнительно можно очистить состояние SSL через свойства интернета: inetcpl.cplСодержаниеОчистить состояние SSL.

6) Расширения браузера — блокировщики, прокси-расширения и инструменты безопасности могут вмешиваться в сетевые запросы. Быстрая проверка: открыть сайт в профиле без расширений или во временном чистом профиле Chrome.

Если после этих шагов ошибка сохраняется у многих пользователей, переходите к серверу.

Серверные причины ERR_SSL_PROTOCOL_ERROR

Для владельца сайта ERR_SSL_PROTOCOL_ERROR чаще всего означает, что HTTPS настроен некорректно. Ниже — основные сценарии.

1) На порту 443 работает не TLS — классическая ошибка: Nginx или приложение слушает 443, но отдаёт обычный HTTP. Браузер ожидает TLS-рукопожатие, а получает текстовый ответ, поэтому соединение падает. Проверьте, что виртуальный хост для 443 содержит ssl и корректные директивы сертификата.

2) Сертификат не соответствует домену — сервер может отдавать сертификат для другого имени, например default.example.net вместо example.com. Это часто связано с неправильным server_name, отсутствием SNI-конфигурации или дефолтным виртуальным хостом. Особенно внимательно проверяйте www и non-www версии домена.

3) Неполная цепочка сертификатов — сервер должен отдавать не только leaf-сертификат сайта, но и промежуточные сертификаты. Если цепочка неполная, часть клиентов не сможет построить доверие. В Nginx нужно использовать fullchain.pem, а не только cert.pem.

4) Просроченный или ещё не активный сертификат — Chrome чаще показывает отдельную ошибку сертификата, но при проблемах с цепочкой, CDN или прокси это может проявиться и как протокольный сбой. Проверяйте дату сертификата на всех слоях: origin, CDN, load balancer, ingress.

5) Несовместимые версии TLS — если сервер поддерживает только старые TLSv1.0/TLSv1.1, современные браузеры могут отказаться от соединения. Обратная ситуация тоже возможна: старый клиент не умеет TLSv1.2/TLSv1.3. Для публичного сайта нормальная базовая настройка — TLSv1.2 и TLSv1.3.

6) Неподдерживаемые cipher suites — сервер и клиент должны найти общий набор шифров. Если администратор слишком жёстко ограничил ssl_ciphers, часть клиентов перестанет подключаться. Это особенно заметно после «усиления безопасности» без проверки совместимости.

7) Ошибка SNI — SNI позволяет браузеру передать имя сайта в начале TLS-рукопожатия, чтобы сервер выбрал правильный сертификат. Если reverse proxy, балансировщик или CDN неправильно передаёт SNI, клиент получает не тот сертификат или соединение закрывается. Подробнее об этом механизме — в материале про SNI и ALPN.

8) Конфликт настроек HTTP/2, ALPN или CDN — браузер договаривается не только о TLS, но и о прикладном протоколе через ALPN: например, h2 или http/1.1. Ошибки здесь встречаются реже, но возможны после обновления Nginx, OpenSSL, CDN-конфигурации или балансировщика.

Диагностика через curl, OpenSSL и логи

Браузер скрывает детали, поэтому для диагностики нужны инструменты командной строки. Начните с curl: он покажет, на каком этапе ломается соединение.

curl -vI https://example.com

Смотрите на строки про TLS: версию протокола, сертификат, ошибку проверки, момент обрыва. Если curl пишет wrong version number, сервер часто отдаёт HTTP на HTTPS-порту. Если handshake failure — проблема в версии TLS, шифрах, SNI или политике сервера.

Для проверки сертификата и SNI используйте openssl:

openssl s_client -connect example.com:443 -servername example.com -showcerts

Что смотреть в выводе:

  • subject — на какой домен выпущен сертификат;
  • issuer — кто выпустил сертификат;
  • Verify return code: 0 (ok) — цепочка валидна;
  • Protocol — согласованная версия TLS;
  • Cipher — выбранный набор шифров;
  • наличие промежуточных сертификатов в Certificate chain.

Если без -servername сервер отдаёт один сертификат, а с -servername example.com другой, значит SNI действительно влияет на результат. Это нормально для хостинга с несколькими сайтами на одном IP, но критично, чтобы нужный домен получал нужный сертификат.

Проверьте конкретные версии TLS:

openssl s_client -connect example.com:443 -servername example.com -tls1_2
openssl s_client -connect example.com:443 -servername example.com -tls1_3

Если TLS 1.2 не работает, а TLS 1.3 работает, часть клиентов может отвалиться. Если наоборот, возможна несовместимость старого OpenSSL, балансировщика или CDN.

Логи тоже важны. Для Nginx смотрите:

  • /var/log/nginx/error.log;
  • /var/log/nginx/access.log;
  • логи контейнера, если Nginx запущен в Docker;
  • логи ingress-контроллера в Kubernetes;
  • события CDN или WAF.

Ищите сообщения вроде SSL_do_handshake() failed, no shared cipher, bad key share, unknown protocol, client sent plain HTTP request to HTTPS port.

Для удобной ручной проверки HTTP-запросов пригодится отдельный разбор, что такое curl и как им пользоваться.

Как исправить ошибку в Nginx, CDN и reverse proxy

Большинство серверных случаев сводится к неправильной связке: домен → DNS → CDN или балансировщик → Nginx → приложение. Проверять нужно каждый слой.

1) Убедитесь, что Nginx слушает 443 ssl — конфигурация должна явно включать SSL для HTTPS-сервера. Минимальный фрагмент выглядит так:

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
 
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
 
    ssl_protocols TLSv1.2 TLSv1.3;
 
    location / {
        proxy_pass http://127.0.0.1:3000;
    }
}

Если оставить listen 443; без ssl в старых конфигурациях или прокинуть на этот порт обычное приложение — получите ту же ошибку у пользователей.

2) Проверьте, что используется fullchain.pem, а не cert.pem — иначе часть клиентов не сможет построить цепочку доверия до промежуточного сертификата.

3) Проверьте server_name — сертификат должен покрывать все имена, которые используют пользователи: example.com, www.example.com, поддомены. Если www ведёт на сервер, но сертификат выпущен только на корневой домен, будут ошибки.

4) Настройте редирект с HTTP на HTTPS отдельно — порт 80 должен принимать обычный HTTP и делать редирект:

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

Не пытайтесь обслуживать TLS на 80 или plain HTTP на 443. Это частая причина странных браузерных ошибок.

5) Проверьте CDN-режим SSL — у CDN обычно есть режимы вроде Flexible, Full, Full strict. Ошибка возникает, когда CDN принимает HTTPS от пользователя, но к origin идёт по неправильной схеме или не доверяет сертификату origin. Для продакшена безопаснее использовать полный TLS до origin и валидный сертификат на origin-сервере.

6) Проверьте балансировщик и ingress — TLS может завершаться на load balancer, а дальше трафик идёт в Nginx или приложение. Если TLS завершается дважды или, наоборот, не завершается нигде, клиент увидит протокольный сбой. Зафиксируйте схему: где именно заканчивается TLS, какие порты слушают backend-сервисы, какой протокол ожидает каждый upstream.

7) Перезагрузите конфигурацию после проверки — перед reload выполните:

nginx -t
systemctl reload nginx

Если сайт на Nginx и Let's Encrypt, полезна пошаговая инструкция по настройке HTTPS и бесплатного SSL-сертификата в Nginx.

Сертификаты Let's Encrypt: продление и типовые ошибки

Многие инциденты с ERR_SSL_PROTOCOL_ERROR появляются не в момент первой настройки HTTPS, а во время автоматического продления сертификата или деплоя.

1) Certbot обновил сертификат, но Nginx не перечитал его — файлы в /etc/letsencrypt/live/... обновились, но процесс Nginx продолжает использовать старый сертификат. Нужен reload после успешного renew. Обычно это делается deploy hook:

certbot renew --deploy-hook "systemctl reload nginx"

2) Сертификат выпущен не на все имена — например, команда выпускала сертификат только для example.com, а пользователи заходят на www.example.com. Проверьте Subject Alternative Name через браузер, openssl или панель центра сертификации.

3) DNS указывает на старый сервер — вы обновили сертификат на новом сервере, но часть пользователей из-за DNS-кэша попадает на старый IP. Там может быть просроченный или чужой сертификат. Проверьте A/AAAA-записи и фактический IP из разных сетей.

4) Несколько копий Nginx или контейнеров — в Docker/Kubernetes сертификат может обновиться на хосте, но не попасть внутрь контейнера. Или ingress использует секрет Kubernetes, который не обновился. Проверяйте не только файлы на сервере, но и тот сертификат, который реально отдаётся извне.

5) Неправильные права на ключ — Nginx должен иметь возможность прочитать privkey.pem. После переноса файлов или изменения пользователя процесса может появиться ошибка загрузки ключа. Тогда HTTPS-виртуальный хост не поднимется корректно.

Для автоматизации продления пригодится отдельная инструкция: как настроить автоматическое обновление сертификатов Let's Encrypt с помощью certbot.

Чеклист исправления для владельца сайта

Если пользователи жалуются на ERR_SSL_PROTOCOL_ERROR, пройдите по короткому списку — большинство пунктов уже разобраны выше.

1) Подтвердите масштаб — проверьте сайт из другой сети, в другом браузере и через curl -vI https://domain. Если ошибка только у одного пользователя, разбирайтесь с локальными причинами: время, кэш, VPN, антивирус.

2) Проверьте DNS — сверьте A/AAAA-записи для домена и www. Часто забывают про IPv6: по IPv4 всё работает, а AAAA указывает на сервер без корректного TLS.

3) Проверьте порт 443 — он должен быть открыт на firewall, балансировщике и сервере и отвечать именно TLS, а не обычным HTTP.

4) Проверьте сертификат через openssl s_client -servername — убедитесь, что он выпущен на нужное имя, не просрочен и передаётся с полной цепочкой.

5) Проверьте версии TLS и конфигурацию Nginx — оставьте TLSv1.2/TLSv1.3, выполните nginx -t, посмотрите error.log и перезагрузите конфигурацию. Если сайт за CDN — проверьте режим SSL и сертификат origin.

6) Проверьте результат извне — не ограничивайтесь браузером на сервере, используйте внешний curl, openssl и мониторинг доступности. Statuser может регулярно проверять HTTPS-страницу и присылать уведомления, если сайт перестал открываться или начал отвечать с ошибкой.

7) Зафиксируйте причину инцидента — если проблема была в продлении сертификата, добавьте reload hook. Если в CDN — опишите правильный режим SSL. Если в IPv6 — добавьте проверку AAAA в регулярный чеклист. Без этого ошибка вернётся при следующем деплое.

Дополнительно стоит настроить отдельный контроль срока действия и валидности сертификата. Подробнее об этом — в статье почему важен мониторинг SSL-сертификатов.

Как предотвратить повторение ошибки

Полностью исключить TLS-инциденты нельзя, но можно сделать их редкими и быстро обнаруживаемыми.

1) Храните конфигурацию как код — Nginx, ingress, балансировщики и CDN-настройки должны быть описаны в репозитории или IaC. Ручные изменения через панель часто становятся причиной расхождений: один домен работает, другой отдаёт дефолтный сертификат.

2) Проверяйте HTTPS после деплоя — добавьте smoke-тест: curl -fI https://domain, проверка сертификата, проверка редиректа с HTTP на HTTPS. Для нескольких доменов автоматизируйте список.

3) Следите за цепочкой сертификатов — проверяйте не только дату окончания, но и соответствие SAN, промежуточные сертификаты, фактический сертификат на CDN и origin.

4) Не меняйте TLS-политику вслепую — ужесточение ssl_ciphers, отключение TLSv1.2, включение новых параметров HTTP/2 или HTTP/3 нужно тестировать. Иначе часть пользователей начнёт получать браузерные ошибки без понятной жалобы в логах приложения.

5) Разделяйте ответственность слоёв — если TLS завершается на CDN, origin должен быть настроен под этот сценарий. Если TLS завершается на Nginx, приложение за ним не должно ожидать HTTPS напрямую. Чем понятнее схема, тем проще искать сбой.

6) Документируйте аварийные команды — где смотреть логи, как проверить сертификат, как перезагрузить Nginx, как временно отключить проблемный CDN-режим. Во время инцидента это экономит больше времени, чем длинные общие инструкции.

FAQ

Почему Chrome показывает ERR_SSL_PROTOCOL_ERROR, а сайт у меня «работает»?
Возможно, вы проверяете из кэша, из другой сети или через другой путь. Проверьте сайт извне через curl и openssl, а также в другом браузере и с мобильного интернета.

Может ли ошибка быть из-за просроченного SSL-сертификата?
Да, хотя Chrome часто показывает отдельное сообщение о недействительном сертификате. При проблемах с CDN, цепочкой или прокси просрочка может выглядеть как общий TLS-сбой.

Что значит wrong version number в curl?
Часто это означает, что на HTTPS-порту 443 сервер отдаёт обычный HTTP или другой не-TLS-протокол. Проверьте listen 443 ssl, reverse proxy и балансировщик.

Нужно ли включать TLS 1.0 ради совместимости?
Для публичного сайта обычно нет. Нормальная базовая настройка — TLSv1.2 и TLSv1.3. Старые протоколы небезопасны и могут ухудшить оценку HTTPS-конфигурации.

Опубликовано 27 августа 202610 минут чтенияДенис Коршунов
Средний рейтинг статьи — 4.8

Настроить мониторинг за 30 секунд

Надежные оповещения о даунтаймах. Без ложных срабатываний