ERR_SSL_VERSION_OR_CIPHER_MISMATCH: сервер и браузер не сошлись в версии TLS и шифрах
Сертификат свежий, порт 443 открыт, а Chrome показывает «Этот сайт не может обеспечить безопасное соединение» и код -113. Это не ошибка сертификата и не ошибка сети: клиент и сервер не нашли ни одной общей пары «версия TLS + набор шифров». Разбираем, где это ломается, как найти причину через openssl и nmap и какой конфиг поставить, не сломав старых клиентов.
ERR_SSL_VERSION_OR_CIPHER_MISMATCH (код Chromium -113) — ошибка TLS-рукопожатия, при которой у клиента и сервера нет ни одной общей версии протокола или ни одного общего набора шифров. Chromium выдаёт её, когда сервер отвечает на ClientHello алертом protocol_version, insufficient_security или handshake_failure либо когда BoringSSL не находит общий шифр. Почти всегда причина на сервере: включены только TLS 1.0/1.1, только ГОСТ-шифры, только устаревшие наборы вроде RC4 и 3DES или нет сертификата под запрошенное имя.
Чем -113 отличается от ERR_SSL_PROTOCOL_ERROR
Код -107 (SSL_PROTOCOL_ERROR) означает «сервер нарушил протокол»: прислал мусор вместо TLS-записи, оборвал рукопожатие, отдал HTTP на 443-м порту. Код -113 конкретнее: обе стороны говорят на TLS правильно, но не могут договориться о параметрах; в net_error_list.h Chromium — «The client and server don't support a common SSL protocol version or cipher suite». Общий случай разобран в статье про ERR_SSL_PROTOCOL_ERROR, здесь — только несовпадение параметров. Какие события BoringSSL превращаются в -113, видно в net/ssl/openssl_ssl_util.cc:
| Что получил BoringSSL | Код Chromium | Типичная причина на сервере |
|---|---|---|
| Алерт protocol_version (70) | -113 | Сервер принимает только TLS 1.0/1.1 или только TLS 1.3, а клиент — нет |
| Алерт handshake_failure (40) сразу после ClientHello | -113 | Нет общего шифра, нет сертификата под запрошенное имя |
| Алерт insufficient_security (71); NO_SHARED_CIPHER или UNSUPPORTED_PROTOCOL внутри BoringSSL | -113 | Сервер требует или выбрал параметры, которых клиент не предлагал |
| Алерт unrecognized_name (112) | -159 UNRECOGNIZED_NAME_ALERT | nginx с ssl_reject_handshake on для неизвестного SNI |
| handshake_failure в середине рукопожатия, любой другой сбой | -107 PROTOCOL_ERROR | Обрыв, не-TLS ответ, ошибка в самом протоколе |
Какие версии TLS браузеры принимают на сентябрь 2026
Живых версий две: TLS 1.2 и TLS 1.3. Всё, что старше, три основных браузера отключили в 2020 году, а RFC 8996 (март 2021, BCP 195) перевёл TLS 1.0 и 1.1 в статус Historic и обязал серверы отвечать на них алертом protocol_version — тем, который Chrome показывает как -113.
| Версия | Год, RFC | Статус | Chrome / Firefox / Safari |
|---|---|---|---|
| SSL 2.0 | 1995 | Запрещён RFC 6176 (2011) | Нет нигде, код удалён |
| SSL 3.0 | 1996 | Запрещён RFC 7568 (2015), POODLE | Отключён: Chrome 40, Firefox 34 (2014), Safari 9 (2015) |
| TLS 1.0 | 1999, RFC 2246 | Historic, RFC 8996 (2021) | Chrome 84 (июль 2020, предупреждение), Chrome 98 (февраль 2022, теперь -113) · Firefox 78 (июнь 2020) · Safari 13.1, iOS 13.4 / macOS 10.15.4 (март 2020) |
| TLS 1.1 | 2006, RFC 4346 | Historic, RFC 8996 (2021) | Те же даты, что у TLS 1.0 |
| TLS 1.2 | 2008, RFC 5246 | Действующий | Везде; минимум, который принимают современные браузеры |
| TLS 1.3 | 2018, RFC 8446 | Действующий | Chrome 70, Firefox 63 (2018), Safari 12.1 / iOS 12.2 (2019) |
Деталь про Chrome: в версии 84 сайт на TLS 1.0/1.1 ещё открывался через страницу-предупреждение ERR_SSL_OBSOLETE_VERSION, а политика SSLVersionMin позволяла вернуть старые версии. В Chrome 98 этот код удалили, и с февраля 2022 года такой сервер получает неперешагиваемый -113 — ровно как SSL 3.0.
Почему сервер не может договориться с браузером
Чаще всего виновата конфигурация сервера, и первый кандидат — старая версия TLS. Второй — сертификат: сервер не нашёл его для запрошенного имени и отверг рукопожатие вместо того, чтобы отдать «не тот».
| Причина на сервере | Где встречается | Что видит клиент |
|---|---|---|
| Включены только TLS 1.0/1.1 | Windows Server 2008 (TLS 1.2 нет без KB4019276), 2008 R2 (TLS 1.2 выключен по умолчанию), старые панели хостинга, веб-интерфейсы роутеров и камер | Алерт protocol_version |
| Только ГОСТ-шифры | Госпорталы и СЭД за КриптоПро NGate или stunnel с ГОСТ без RSA/ECDSA-сертификата на том же адресе | handshake_failure: у Chrome нет ни одного из шифров RFC 9189 |
| Только RC4, 3DES или RSA-обмен ключами | ssl_ciphers из статей 2012 года. RC4 удалён из Chrome 48, DHE — из Chrome 52 (2016), 3DES — из Chrome 93 (2021) | handshake_failure |
| Нет сертификата под SNI | Домен направлен на IP, где нет server_name для него; Cloudflare без edge-сертификата на поддомен вида test.dev.example.com; сертификат ещё не выпущен | handshake_failure. У nginx с ssl_reject_handshake — unrecognized_name, код -159 |
| Только ECDSA-сертификат | Клиент без ECDHE-ECDSA-шифров: старая Java, Windows XP, embedded-клиенты | handshake_failure — нет общего шифра для этого ключа |
| Опечатка в ssl_ciphers | Несуществующее имя или !ALL в начале — список пуст, OpenSSL отвергает всех | handshake_failure на всех клиентах сразу |
| RSA короче 1024 бит | Самоподписанные ключи из 2000-х | Другой код: ERR_CERT_WEAK_KEY |
Когда виноват клиент, а не сайт
Если сайт открывается у всех, кроме одного пользователя, — проблема на его стороне. Проверка: та же страница с телефона по мобильному интернету.
| Причина на клиенте | Что происходит | Что делать |
|---|---|---|
| Старая ОС без TLS 1.2 | Windows XP (Schannel умеет максимум TLS 1.0), Android 4.0–4.3 (TLS 1.2 выключен по умолчанию), Windows 7 в приложениях без явно включённого TLS 1.2 | Обновить ОС или поставить браузер со своей TLS-библиотекой (Firefox использует NSS, а не Schannel) |
| Антивирус или прокси с TLS-перехватом | Между браузером и сайтом стоит перехватчик с устаревшим TLS-стеком; в треде Chromium об удалении TLS 1.0 старые антивирусы давали ложную ошибку даже на сервисах Google | Отключить проверку HTTPS в антивирусе, обновить прокси |
| Корпоративная политика | SSLVersionMin поднят до tls1.3, а сайт умеет только 1.2; ограничен список шифров | chrome://policy — искать SSLVersionMin |
| Экспериментальные флаги | chrome://flags: отключённый TLS 1.3, принудительный QUIC или ECH | Сбросить флаги, проверить в чистом профиле |
Как найти, где именно расходятся параметры
Основной инструмент — openssl s_client с принудительной версией и шифром: он показывает, какой алерт прислал сервер. Браузер прячет это за одним кодом -113.
# Что сервер выберет сам openssl s_client -connect site.ru:443 -servername site.ru < /dev/null 2>&1 | grep -E "Protocol|Cipher" # Принудительно версия / шифр openssl s_client -connect site.ru:443 -servername site.ru -tls1_2 < /dev/null openssl s_client -connect site.ru:443 -servername site.ru -tls1_3 < /dev/null openssl s_client -connect site.ru:443 -servername site.ru -tls1_2 -cipher ECDHE-RSA-AES128-GCM-SHA256 < /dev/null # Живы ли TLS 1.0/1.1 (OpenSSL 3 сам их не предлагает) openssl s_client -connect site.ru:443 -servername site.ru -tls1_1 -cipher 'DEFAULT:@SECLEVEL=0' < /dev/null
Характерные ответы (пример вывода OpenSSL 3.0, стенд с одним включённым TLS 1.2):
$ openssl s_client -connect site.ru:443 -tls1_1
error:0A0000BF:SSL routines:tls_setup_handshake:no protocols available
# отказался ваш OpenSSL: TLS 1.1 запрещён на уровне безопасности 1
$ openssl s_client -connect site.ru:443 -tls1_3
error:0A00042E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version
SSL alert number 70
# сервер: такой версии нет
$ openssl s_client -connect site.ru:443 -tls1_2 -cipher AES256-SHA
error:0A000410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
SSL alert number 40
# версия подошла, общего шифра нет
$ openssl s_client -connect site.ru:443 -tls1_2
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
# договорились
| Сообщение openssl | Кто отказал | Что значит |
|---|---|---|
| no protocols available | Ваш клиент | Запрошенная версия запрещена локальной политикой OpenSSL. Сервер даже не опрошен |
| tlsv1 alert protocol version (70) | Сервер | Ни одна из предложенных версий не включена на сервере. В Chrome — -113 |
| sslv3 alert handshake failure (40) | Сервер | Версия подошла, но нет общего шифра, нет сертификата под SNI или сертификат не подходит к шифрам. В Chrome — -113 |
| tlsv1 alert insufficient security (71) | Сервер | Сервер требует более сильные параметры, чем предложил клиент. В Chrome — -113 |
| tlsv1 unrecognized name (112) | Сервер | Имя из SNI серверу неизвестно. В Chrome — -159 |
| wrong version number / unexpected eof | Сервер или сеть | На порту не TLS или соединение оборвано. В Chrome — -107 |
Полную картину по версиям и шифрам даёт nmap: он перебирает наборы сам и выставляет оценки от A до F.
$ nmap --script ssl-enum-ciphers -p 443 site.ru # пример вывода
443/tcp open https
| ssl-enum-ciphers:
| TLSv1.0:
| ciphers:
| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
| warnings:
| 64-bit block cipher 3DES vulnerable to SWEET32 attack
| TLSv1.2:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|_ least strength: C
# TLS 1.0 всё ещё включён, TLS 1.3 не появился вовсе
Для отчёта с уязвимостями удобнее testssl.sh — bash-скрипт, которому нужен только openssl: testssl.sh -p site.ru покажет версии, -E — шифры по каждой версии. Из curl достаточно curl -v --tlsv1.2 https://site.ru/: в выводе будет либо «TLS alert, protocol version», либо «SSL connection using TLSv1.3». Если ошибка воспроизводится у одного пользователя, попросите его записать chrome://net-export: в журнале есть номер алерта, а не только код -113.
Как исправить: TLS 1.2 + 1.3 и профиль intermediate
Ответ для любого веб-сервера один: включить TLS 1.2 и 1.3, а список шифров взять из профиля intermediate конфигуратора Mozilla (проект переехал под имя TLSRef, версия рекомендаций 6.0 на сентябрь 2026). Профиль совместим с Chrome 49, Firefox 31, Safari 9, Android 4.4.2, Java 8u161 — клиентами десятилетней давности.
| Сервер | Версии | Шифры и особенности |
|---|---|---|
| nginx | ssl_protocols TLSv1.2 TLSv1.3; | ssl_ciphers — список ниже; ssl_prefer_server_ciphers off. С 1.23.4 (март 2023) это дефолт, но старые конфиги его переопределяют |
| Apache 2.4 | SSLProtocol -all +TLSv1.2 +TLSv1.3 | SSLCipherSuite тот же список; SSLHonorCipherOrder off. Дефолт «all -SSLv3» оставляет TLS 1.0/1.1 |
| Caddy 2 | tls { protocols tls1.2 tls1.3 } | Это и есть дефолт, править не нужно. Шифры TLS 1.3 не настраиваются |
| HAProxy | ssl-default-bind-options ssl-min-ver TLSv1.2 | ssl-default-bind-ciphers для TLS 1.2, ssl-default-bind-ciphersuites для 1.3 — в секции global |
| IIS / Windows | Реестр SCHANNEL\Protocols\TLS 1.2\Server: Enabled=1, DisabledByDefault=0 | TLS 1.3 только с Windows Server 2022. Ветки TLS 1.0/1.1 — Enabled=0. Нужен перезапуск |
| Cloudflare | Edge Certificates → Minimum TLS Version = 1.2 | Шифры на edge свои; edge-сертификат должен покрывать все поддомены |
# nginx, профиль intermediate (TLSRef 6.0, сентябрь 2026) ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; ssl_prefer_server_ciphers off; ssl_session_timeout 1d; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; # проверка и перезагрузка nginx -t && nginx -s reload openssl s_client -connect site.ru:443 -servername site.ru -tls1_2 < /dev/null | grep Cipher
Совместимость со старыми клиентами — вопрос только о TLS 1.2. Если кто-то ломается на TLS 1.3 (старые Java 8, некоторые прокси), можно временно оставить ssl_protocols TLSv1.2; — браузеры разницы не заметят. Возврат TLS 1.0/1.1 не даст ничего: Chrome, Firefox и Safari к ним не подключатся, а PCI DSS запретил TLS 1.0 для платёжных систем ещё с 30 июня 2018 года.
nginx -t строку шифров не проверяет. Если ни одно имя не совпало с вашей версией OpenSSL, сервер отвечает handshake_failure всем подряд. Перед reload выполните openssl ciphers -v 'ВАША-СТРОКА' | wc -l: ноль строк — публиковать нельзя.
Почему Chrome не открывает сайты с ГОСТ TLS
ГОСТ-шифры для TLS 1.2 описаны в RFC 9189 (март 2022): TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC (0xC100), TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC (0xC101) и TLS_GOSTR341112_256_WITH_28147_CNT_IMIT (0xC102). Документ имеет статус Informational, и BoringSSL, NSS и TLS-стек Apple эти наборы не реализуют. Если на сервере включены только они, в ClientHello обычного Chrome нет ни одного знакомого серверу шифра — тот отвечает handshake_failure, браузер показывает -113.
Открыть такой сайт можно только браузером с внешним криптопровайдером. Подтверждённые варианты на сентябрь 2026: Яндекс Браузер с КриптоПро CSP (опция «Подключаться к сайтам, использующим шифрование по ГОСТ») и Chromium-Gost — открытая сборка Chromium, которую сопровождает сообщество при участии КриптоПро; есть версии для Windows, Linux, macOS и Android. Решение со стороны владельца — держать ГОСТ и обычный TLS параллельно: ГОСТ-терминатор на отдельном порту или адресе, а на основном 443 — сертификат RSA/ECDSA.
Как не пропустить момент, когда конфиг сломал HTTPS
Ошибка -113 появляется после ваших же действий: обновили OpenSSL, применили список шифров из чужого гайда, переехали на Cloudflare и забыли про поддомен третьего уровня. Сервер жив, порт 443 отвечает, ping проходит — а curl с той же машины договорится там, где старый клиент уже нет. Почему клиент и сервер вообще «торгуются» о параметрах, разобрано в статье о том, как работает HTTPS.
Снаружи это ловится двумя проверками. Проверка SSL-сертификата устанавливает полное TLS-соединение с внешней точки: если рукопожатие не проходит, инцидент откроется независимо от срока сертификата. А HTTP-проверка по адресу https:// зафиксирует, что страница перестала отдаваться, с интервалом от 2 минут — это и есть время обнаружения.
Пруфен проверяет HTTPS-доступность и состояние TLS из 13 точек мониторинга — 11 в России, а также Минск и Испания — и присылает уведомление в Email, Telegram или Макс, как только рукопожатие перестало проходить; если ресурс так и не поднялся, подключается голосовой звонок. Результат виден по каждой точке отдельно: ошибка конфига падает везде, проблема региона — в одной точке. Бесплатный план — 5 проверок.
Частые вопросы
Сайт открывается в Firefox, но не в Chrome. Как так?
У браузеров разные TLS-библиотеки и списки шифров: Chrome использует BoringSSL, Firefox — NSS. Chrome удалил DHE-наборы в 2016 году, Firefox держал их дольше: если сервер предлагает только DHE-RSA-шифры, Firefox договорится, Chrome — нет. Диагноз ставится через nmap --script ssl-enum-ciphers: в списке сервера должен быть хотя бы один ECDHE-набор с AES-GCM или ChaCha20.
Можно ли разрешить Chrome старый TLS, как раньше через флаги?
Нет. Страница-предупреждение ERR_SSL_OBSOLETE_VERSION и обход через политику удалены из Chromium в версии 98 (февраль 2022). Единственный способ — исправить сервер; для старых IPMI и роутеров — прокси, который терминирует современный TLS снаружи.
Ошибка появляется не на всех страницах сайта, а только на поддомене. Что это?
Почти наверняка сертификат под этот поддомен не выпущен или не привязан. У Cloudflare Universal SSL покрывает example.com и *.example.com, но не test.dev.example.com — на такой хост edge отвечает handshake_failure. У nginx то же даёт запрос на IP, где для этого server_name нет блока с сертификатом. Проверка: openssl s_client с -servername поддомена и без него — разные результаты означают проблему SNI.
Оставить только TLS 1.3 — безопаснее?
Немного, но ценой части клиентов: профиль modern требует минимум Chrome 70, Firefox 63, Safari 12.1, Android 10, Java 11. Старые Java-интеграции и API-клиенты партнёров отвалятся с той же ошибкой. TLS 1.2 с ECDHE и AEAD-шифрами достаточен; отключайте его, только если знаете всех своих клиентов.
Чем это отличается от «Подключение не защищено»?
Стадией. «Подключение не защищено» — рукопожатие прошло, но сертификат не прошёл проверку: истёк, выдан на другое имя, подписан неизвестным центром; такую страницу часто можно пролистать. ERR_SSL_VERSION_OR_CIPHER_MISMATCH возникает раньше, до обмена сертификатами, и кнопки обхода у неё нет. Подробнее — в статье про «Подключение не защищено».