NET::ERR_CERT_AUTHORITY_INVALID: браузер не верит вашему сертификату
12 мин чтения
NET::ERR_CERT_AUTHORITY_INVALID: браузер не верит вашему сертификату

NET::ERR_CERT_AUTHORITY_INVALID: браузер не верит вашему сертификату

Сертификат куплен и установлен, в панели хостинга зелёная галочка — а Chrome показывает красный экран с кодом NET::ERR_CERT_AUTHORITY_INVALID, причём у половины пользователей всё открывается. Это не ошибка шифрования и не истёкший срок: браузер не смог провести цепочку от вашего сертификата до корня, которому доверяет. Разбираем, где рвётся цепочка доверия, как за минуту поставить диагноз через openssl и что править в nginx, Apache и Caddy.

NET::ERR_CERT_AUTHORITY_INVALID — ошибка Chromium (код −202), означающая, что сертификат сайта подписан удостоверяющим центром, которому браузер не доверяет: цепочка сертификатов не доходит до корневого сертификата из хранилища доверия браузера или операционной системы. Причина бывает на сервере (самоподписанный сертификат, не отдана промежуточная цепочка, корень не входит в публичные root-программы) и на клиенте (антивирус, корпоративный прокси, старая ОС без нужного корня). Сам сертификат при этом может быть исправным.

Что именно проверяет браузер и где рвётся цепочка

Браузер не «знает» ваш сертификат — он знает несколько сотен корневых из своего хранилища и проверяет, можно ли добраться от них до вашего по цепочке подписей. Алгоритм описан в RFC 5280, раздел 6.1: для каждого звена проверяется подпись издателя, срок действия, статус отзыва и совпадение имени издателя с субъектом следующего сертификата. Начало пути — trust anchor, «якорь доверия». Сервер обязан отдать в рукопожатии свой сертификат и все промежуточные; корень браузер берёт у себя.

Хранилищ несколько, и они разные. С Chrome 105 на Windows и macOS (по умолчанию — с 108), с 114 на Linux и с 115 на Android браузер использует собственный Chrome Root Store, но локально добавленные в ОС корни учитывает; на iOS работает хранилище Apple. Firefox всегда использовал своё хранилище NSS (Mozilla Root Program) и лишь с версии 120 импортирует добавленные пользователем корни из ОС. Отсюда картина «в Safari открывается, в Firefox — нет».

Второе отличие: настольные браузеры умеют «дочинить» неполную цепочку — Chrome кэширует и догружает промежуточные сертификаты, Firefox с версии 68 предзагружает их список из базы CCADB (более двух тысяч записей). Мобильные приложения, curl и старые Android так не делают; документация Android называет отсутствие промежуточного сертификата на сервере одной из самых частых причин SSLHandshakeException. Поэтому «у меня в Chrome работает» — не аргумент.

Семейство ERR_CERT_*: какой код что означает

Ошибки сертификата в Chromium занимают диапазон от −200 до −219 в файле net_error_list.h, и код на экране точно говорит, что не прошло проверку. Экран «Подключение не защищено» одинаков для всех, разница — в строке с кодом внизу.

Код Chromium Что не прошло Чья сторона «Перейти всё равно»
−200 CERT_COMMON_NAME_INVALID Имя в сертификате не совпадает с хостом Сайт Есть
−201 CERT_DATE_INVALID По часам клиента сертификат истёк или ещё не начался Сайт или клиент Есть
−202 CERT_AUTHORITY_INVALID Подписан УЦ, которому браузер не доверяет Сайт или клиент Есть
−203 CERT_CONTAINS_ERRORS Сертификат повреждён Сайт Нет — «not recoverable»
−207 CERT_INVALID Прочая невалидность Сайт Нет — «not recoverable»
−214 CERTIFICATE_TRANSPARENCY_REQUIRED Нет отметок CT-логов Сайт (УЦ) Есть

Кнопка «Перейти на сайт (небезопасно)» прячется под «Дополнительно», но на доменах с HSTS браузер её не показывает. Код −214 стоит отдельно: с 30 апреля 2018 года Chrome требует записи каждого публично доверенного сертификата в логи Certificate Transparency — минимум 2 отметки SCT при сроке до 180 дней и 3 при большем. Публичные УЦ делают это сами; ошибка всплывает у корпоративных перехватчиков трафика.

Причины на стороне сайта

Если ошибку видят все пользователи во всех сетях — проблема в том, что отдаёт сервер.

Причина Как выглядит в openssl Кто пострадает
Не отдана промежуточная цепочка (в nginx указан cert.pem вместо fullchain.pem) num=20 unable to get local issuer certificate, затем num=21 unable to verify the first certificate Firefox, Android, приложения, curl; в Chrome часто «работает»
Самоподписанный сертификат num=18 self-signed certificate Все
Корпоративный, тестовый или Cloudflare Origin CA num=19 self-signed certificate in certificate chain Все, у кого нет этого корня
Сертификат НУЦ Минцифры num=19 или 20 — корня нет в публичных хранилищах Chrome, Firefox, Safari, Edge без установки корня
Истёкший корень в цепочке (DST Root CA X3) num=10 certificate has expired на глубине 2–3 Старые клиенты, OpenSSL 1.0.x
Промежуточный в файле раньше листового nginx не стартует: key values mismatch Все — сайт лежит целиком

Кейс с DST Root CA X3 до сих пор аукается. Этот корень, которым IdenTrust перекрёстно подписал ISRG Root X1 от Let's Encrypt, истёк 30 сентября 2021 года. Android до 7.1.1 не содержит ISRG Root X1, но не проверяет срок действия корней — поэтому Let's Encrypt отдавал «длинную» цепочку через истёкший корень ещё почти три года: с 8 февраля 2024 года не по умолчанию, с 6 июня 2024-го — никак. На сентябрь 2026 года цепочка для RSA: сертификат сайта ← YR1/YR2 ← Root YR ← ISRG Root X1, который действует до 4 июня 2030 года. Устройство без него увидит именно ERR_CERT_AUTHORITY_INVALID.

Причины на стороне клиента

Если ошибку видит один пользователь или одна сеть, а openssl снаружи возвращает «Verify return code: 0 (ok)» — сервер ни при чём: между браузером и сайтом кто-то подменяет цепочку или не знает нужного корня.

Причина Признак Что делать пользователю
Сбитые часы на устройстве Обычно DATE_INVALID; при сдвиге на годы «истекает» и корень Включить автосинхронизацию времени
Антивирус с проверкой HTTPS Издатель в свойствах сертификата — Kaspersky, ESET, Dr.Web Отключить проверку HTTPS или переустановить корень антивируса
Корпоративный прокси / DPI Только в офисной сети, издатель — внутренний CA Корень ставит ИТ-служба
Публичный Wi-Fi с captive portal На любом сайте до авторизации в сети Открыть любой http-адрес, пройти авторизацию
Старая ОС без нужного корня Windows 7/XP без обновлений, Android 4–6: нет ISRG Root X1 Обновить ОС или взять Firefox со своим хранилищем
Сайт на сертификате НУЦ Минцифры Открывается в Яндекс Браузере, в Chrome — нет Установить корни НУЦ или сменить браузер
Антивирус — это штатный man-in-the-middle

«Проверка защищённых соединений» работает единственным способом: антивирус расшифровывает трафик, а браузеру предъявляет сертификат от собственного корня. Пока корень в хранилище ОС — всё прозрачно; после чистки хранилища или в Firefox старше 120 каждый HTTPS-сайт превращается в ERR_CERT_AUTHORITY_INVALID. Проверка — клик по замку: кто издатель.

Как за минуту понять, чья это проблема

Одна команда openssl показывает цепочку, которую отдаёт сервер, и вердикт по ней. Ключ -servername обязателен: без SNI сервер с несколькими сайтами отдаст сертификат по умолчанию. Ниже — реальные выводы против тестовых хостов badssl.com, сокращённые.

openssl s_client -connect incomplete-chain.badssl.com:443 \
  -servername incomplete-chain.badssl.com -showcerts </dev/null

depth=0 CN = *.badssl.com
verify error:num=20:unable to get local issuer certificate
verify error:num=21:unable to verify the first certificate
---
Certificate chain
 0 s:CN = *.badssl.com
   i:C = US, O = Let's Encrypt, CN = YR2   <- издатель назван, но не прислан
---
Verify return code: 21 (unable to verify the first certificate)

В блоке Certificate chain одна запись — сервер прислал только листовой сертификат. Пара num=20 + num=21 — сигнатура неполной цепочки, лечится на сервере. Другие вердикты:

# Самоподписанный
verify error:num=18:self-signed certificate
Verify return code: 18 (self-signed certificate)

# Цепочка упирается в чужой корень (свой CA, НУЦ, Cloudflare Origin)
depth=1 CN = BadSSL Untrusted Root Certificate Authority
verify error:num=19:self-signed certificate in certificate chain
Verify return code: 19 (self-signed certificate in certificate chain)

# Всё хорошо
depth=3 C = US, O = Internet Security Research Group, CN = ISRG Root X1
depth=2 C = US, O = ISRG, CN = Root YR
depth=1 C = US, O = Let's Encrypt, CN = YR2
depth=0 CN = *.badssl.com
Verify return code: 0 (ok)

Номера — из заголовка x509_vfy.h OpenSSL: 10 истёк, 18 самоподписанный, 19 самоподписанный в цепочке, 20 нет локального издателя, 21 не удаётся проверить первый сертификат, 62 имя не совпадает. Тот же диагноз одной строкой даёт curl -vI https://example.ru/: при неполной цепочке — «curl: (60) SSL certificate problem: unable to get local issuer certificate», при самоподписанном — «self-signed certificate», при исправной — «SSL certificate verify ok» с датами start/expire. Ключ -k отключает проверку и годится только чтобы убедиться, что сервер вообще отвечает.

Дальше — сузить круг. Проверка из другой сети (мобильный интернет вместо офисного Wi-Fi) отсекает прокси и антивирус, с другого устройства — часы и старую ОС. Если рук в другом регионе нет, цепочку снимает внешняя точка мониторинга: там нет ни антивируса, ни корпоративного CA. В Chrome цепочка видна через замок → «Сертификат действителен» → «Подробно». Тест SSL Labs промоделирует рукопожатие для десятков клиентов, включая старые Android; неполная цепочка режет оценку до B, недоверенная — до T. Как читать поля сертификата — в статье о проверке SSL-сертификата.

Сертификат НУЦ Минцифры: какие браузеры ему доверяют

Корень Russian Trusted Root CA Национального удостоверяющего центра Минцифры не входит ни в Chrome Root Store, ни в Mozilla NSS, ни в хранилища Apple и Microsoft — сайт на таком сертификате в Chrome, Firefox, Safari и Edge даёт ту же ERR_CERT_AUTHORITY_INVALID, что и корпоративный CA. Минцифры 9 марта 2022 года рекомендовало пользователям Госуслуг Яндекс Браузер и Atom как браузеры с поддержкой российских сертификатов; Яндекс пишет, что ставить сертификаты НУЦ вручную не нужно. На сентябрь 2026 года:

Браузер Что покажет на сайте с сертификатом НУЦ Доверяет НУЦ из коробки
Яндекс Браузер Замок, сайт открывается Да
Atom Замок, сайт открывается Да (по рекомендации Минцифры, 2022)
Chrome NET::ERR_CERT_AUTHORITY_INVALID Нет — только после установки корня в ОС
Edge NET::ERR_CERT_AUTHORITY_INVALID Нет — только после установки корня в ОС
Safari «Это соединение не является частным» Нет — только через профиль/связку ключей
Firefox SEC_ERROR_UNKNOWN_ISSUER Нет — импорт из ОС с версии 120 или вручную в NSS

Сертификат НУЦ годится там, где аудитория на российских браузерах или готова ставить корень руками — так живут банки и госпорталы. Для сайта с трафиком из Chrome и Safari это красный экран у части посетителей.

Как исправить на сервере

Правило одно для всех веб-серверов: в файле лежит листовой сертификат, за ним — промежуточные, от листа к корню; сам корень не нужен. У Let's Encrypt это готовый fullchain.pem, у коммерческих УЦ — «bundle», который приклеивают к своему сертификату.

# Коммерческий УЦ: свой сертификат, затем бандл (порядок критичен)
cat example.ru.crt ca-bundle.crt > example.ru.fullchain.crt

server {
    listen 443 ssl;
    server_name example.ru;
    ssl_certificate     /etc/letsencrypt/live/example.ru/fullchain.pem;  # не cert.pem!
    ssl_certificate_key /etc/letsencrypt/live/example.ru/privkey.pem;
}
nginx -t && systemctl reload nginx

# Проверка после reload: в цепочке должно быть больше одной записи
openssl s_client -connect example.ru:443 -servername example.ru </dev/null 2>/dev/null \
  | grep -E '^ [0-9] s:|Verify return'
Сервер Директива и файл Типичная ошибка
nginx ssl_certificate → fullchain.pem (лист + промежуточные) Указан cert.pem; бандл приклеен перед листом — «key values mismatch»
Apache 2.4.8+ SSLCertificateFile → fullchain.pem; SSLCertificateChainFile устарела с 2.4.8 ChainFile указывает на старый бандл, который УЦ уже сменил
Caddy Автоматически: сертификат от Let's Encrypt/ZeroSSL с полной цепочкой; свой — tls cert.pem key.pem Для localhost Caddy выпускает сертификат своим локальным CA — снаружи он не доверен
Cloudflare (проксирование) Браузер видит edge-сертификат Cloudflare; на origin допустим Origin CA Прокси выключен («серое облако») или аккаунт на паузе — посетители видят Origin CA, которому браузеры не доверяют
Панель хостинга (ISPmanager, cPanel, Plesk) Отдельное поле «Цепочка / CA bundle» при загрузке сертификата Поле пустое — панель молча примет сертификат без цепочки

Соседняя ошибка: ERR_CERT_DATE_INVALID

Код −201: по часам клиента сертификат ещё не начал действовать или уже истёк — в комментарии Chromium так и написано, «by our clock». Отсюда два источника: истёкший сертификат на сервере (видят все, openssl отвечает num=10 certificate has expired и показывает notAfter) и сбитые часы на устройстве (видит один пользователь, Chrome выводит экран «Часы отстают» или «Часы спешат»). Севшая батарейка CMOS, сброшенный планшет, виртуалка без NTP — классика второго случая.

Сертификат Let's Encrypt живёт 90 дней, и автопродление ломается тихо: cron не сработал, порт 80 закрыли, DNS сменился. Истечение — единственная ошибка семейства, предсказуемая на недели вперёд, если кто-то смотрит на notAfter.

Соседняя ошибка: ERR_CERT_COMMON_NAME_INVALID

Код −200: сертификат исправен и доверен, но выпущен не на то имя, что набрано в адресной строке. С Chrome 58 имя проверяется только по расширению subjectAltName (SAN), поле Common Name игнорируется; переходная политика EnableCommonNameFallbackForLocalAnchors существовала с 58 по 65 версию и удалена. Сертификат без SAN в Chrome не работает, даже если CN совпадает.

В SAN сертификата Набрано в браузере Результат
example.ru www.example.ru Ошибка — www не покрыт
example.ru, www.example.ru www.example.ru OK
*.example.ru example.ru Ошибка — wildcard не покрывает голый домен
*.example.ru api.v2.example.ru Ошибка — wildcard покрывает один уровень
CN=example.ru, SAN отсутствует example.ru Ошибка в Chrome с версии 58

Как узнавать о проблеме раньше пользователей

Все три ошибки с сервера не видны: nginx не пишет в лог, что отдал неполную цепочку, истёкший сертификат для него — просто файл. Увидеть их до пользователя можно только регулярной проверкой снаружи, с чистого хранилища доверия: цепочка ломается в момент замены сертификата, истечение — в конкретный день.

Цепочку проверяет внешняя точка, а не ваш браузер

Пруфен выполняет проверку SSL-сертификата с внешних точек мониторинга: валидирует цепочку до доверенного корня, следит за сроком действия и заранее предупреждает об истечении. Уведомление приходит в Email, Telegram или Макс; если ресурс так и не поднялся, подключается голосовой звонок. В бесплатном плане — 5 проверок.

Частые вопросы

Почему в Chrome сайт открывается, а в Firefox и мобильном приложении — ERR_CERT_AUTHORITY_INVALID?
Почти наверняка сервер не отдаёт промежуточный сертификат: Chrome кэширует и догружает промежуточные и маскирует проблему, а приложения и curl недостающие звенья не ищут. Если в openssl s_client в Certificate chain одна запись, а вердикт 20/21 — кладите fullchain.

Можно ли просто установить свой корневой сертификат пользователям?
В корпоративной сети — да, корень внутреннего CA раздаётся групповыми политиками или MDM. Для публичного сайта — нет: нельзя просить каждого посетителя довериться неизвестному корню, а согласившиеся приучаются игнорировать предупреждения. Нужен УЦ, который уже есть в Chrome Root Store, NSS и хранилищах Apple и Microsoft.

Сертификат от Let's Encrypt бесплатный — ему точно доверяют?
Да, ISRG Root X1 входит во все основные root-программы и действует до 2030 года. Проблемы только там, где корня нет: Android до 7.1.1 и системы без обновлений. С июня 2024 года Let's Encrypt не отдаёт цепочку через истёкший DST Root CA X3, и со стороны сервера таким устройствам не помочь — только обновление ОС или браузер со своим хранилищем.

Почему ошибка появляется только на Wi-Fi в кафе или гостинице?
Это captive portal: до авторизации сеть перехватывает запросы и отвечает своей страницей входа с сертификатом, который ни один браузер не признает. Откройте любой адрес по http, пройдите авторизацию — HTTPS заработает. Если ошибка держится и после входа, сеть подменяет трафик постоянно.

Была ли статья полезна?

Начните мониторинг прямо сейчас

Бесплатный тариф — до 5 проверок. 150 ₽ на баланс при регистрации.

Создать аккаунт