Jane Kosykh — AI-автоматизация для бизнеса

Бот перестал отвечать, в логах CERTIFICATE_VERIFY_FAILED: что делать

Опубликовано 1 июл. 2026 г.15 мин чтенияСредний
Бот перестал отвечать, в логах CERTIFICATE_VERIFY_FAILED: что делать
3просмотров

Ваш бот работал год без единой жалобы. А в один день молча замолк. Никто ничего не менял - ни вы, ни подрядчик. Клиент пишет ночью, а в ответ тишина. Утром вы узнаёте, что потеряли заявки, которых даже не видели. Открываете логи сервера - там красное CERTIFICATE_VERIFY_FAILED.

Сам бот при этом исправен. Оборвалось доверие между вашим сервером и российским сервисом, к которому бот подключается по API (программному интерфейсу - каналу, через который программы обмениваются данными). Разберу спокойно: что это значит, как поставить сертификат Минцифры на сервер и починить это за пятнадцать минут, и почему одна и та же ошибка ещё вернётся - уже с GigaChat, банковским сервисом или госуслугами.

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

Подписаться и получить разбор: https://t.me/janeprovideo

Что означает CERTIFICATE_VERIFY_FAILED и почему бот замолчал молча?

Коротко: CERTIFICATE_VERIFY_FAILED значит, что ваш сервер не смог подтвердить подлинность сервиса, к которому подключался бот. Защищённое соединение не состоялось, запрос не ушёл, ответа нет. Бот при этом не падает с грохотом - он просто не может связаться с сервисом. Клиент видит тишину. Ошибка живёт в логах сервера, а не на экране у клиента.

Когда бот подключается к MAX, GigaChat или любому сервису по защищённому каналу, он первым делом проверяет сертификат собеседника. Сертификат - это цифровой паспорт сервиса: он подтверждает, что на том конце действительно тот, за кого себя выдаёт, а не подставной сервер. Ваш сервер смотрит на этот паспорт и решает: доверять или нет.

Если доверия нет, соединение обрывается ещё до того, как уйдёт первый запрос. В логах это выглядит как ssl.SSLCertVerificationError с формулировкой CERTIFICATE_VERIFY_FAILED, а рядом - строка unable to get local issuer certificate. По документации Python это означает буквально следующее:

«A subclass of SSLError raised when certificate validation has failed.» (Перевод: «Подкласс ошибки SSLError, который возникает, когда проверка сертификата не прошла».)

Опасность здесь не в самой ошибке, а в её тишине. Бот не выводит клиенту «извините, техническая проблема». Он просто не отвечает. Если это автономный бот, который держит связь с клиентами круглосуточно, вы теряете заявки ночью и в выходные, а узнаёте об этом, только когда специально заглянете в логи. Молчание опаснее падения: падение видно сразу, тишину - нет.

Почему SSL рвётся именно у российских сервисов?

Коротко: российские сервисы - MAX, GigaChat, госуслуги, банки - переходят на сертификаты Минцифры, выпущенные национальным удостоверяющим центром. Ваш сервер по умолчанию про этот центр ничего не знает: в его списке доверенных лежат только международные. Паспорт сервиса формально настоящий, но выдан «паспортным столом», которого нет в списке, - и сервер захлопывает дверь.

Вернёмся к метафоре с паспортом. Ваш сервер доверяет паспорту по одной причине: его выдал знакомый «паспортный стол» - удостоверяющий центр из заранее известного списка. Красота самого паспорта тут ни при чём. Этот список зашит в систему и по умолчанию состоит из международных центров.

Российские сервисы всё чаще подписывают свои сертификаты у национального удостоверяющего центра Минцифры. В сертификате он записан как Russian Trusted Root CA (корневой) и Russian Trusted Sub CA (промежуточный, он же выпускающий). Это тот самый новый «паспортный стол». Ваш сервер про него ещё не слышал, поэтому паспорт для него незнакомый, и результат - CERTIFICATE_VERIFY_FAILED.

Лечится это добавлением сертификата Минцифры в список доверенных на сервере. Файлы раздаёт сама Минцифра, официальная страница с инструкцией - на Госуслугах (gosuslugi.ru/crt), а сами файлы лежат на gu-st.ru. Важный момент, на котором спотыкаются: ставить нужно оба файла - и корневой, и промежуточный. С одним корневым цепочка доверия часто не достраивается, и ошибка остаётся.

Как отличить сертификат от других причин молчания бота?

Коротко: молчащий бот - это не всегда сертификат. Токен мог протухнуть, сервис - лечь, сеть - отвалиться, домен - смениться. Отличить просто: откройте логи и найдите текст ошибки. CERTIFICATE_VERIFY_FAILED или unable to get local issuer certificate - это сертификат. 401 - токен. Timeout - сеть или сервис. Диагноз ставится за минуту по одной строке.

Прежде чем ставить сертификаты, убедитесь, что дело в них. Иначе можно час чинить не то. Хорошая новость: бот сам подсказывает причину - она написана в логах открытым текстом. Вот таблица, по которой я развожу симптомы.

Что в логахПричинаКуда копать
CERTIFICATE_VERIFY_FAILED, unable to get local issuer certificate, self-signed certificate in certificate chainнет доверенного сертификата (обычно Минцифры)ставить корень Минцифры - разделы ниже
401 Unauthorized, InvalidTokenпротух или неверный токенобновить токен, проверить способ его передачи
Connection timed out, Connection refusedсеть, фаервол или сервис лежитпроверить доступность домена, пинг
Name or service not known, NXDOMAINневерный или сменившийся доменсверить адрес сервиса
404 или 400 на знакомом запросесменился адрес сервисасверить путь с документацией сервиса

Если в логах нет ничего похожего на сертификат - значит, проблема в другом, и разделы про Минцифры вам сейчас не нужны. Если же там CERTIFICATE_VERIFY_FAILED или строка про local issuer - диагноз поставлен, идём чинить.

Молчаливый отвал бота - это деньги, которые утекают незаметно. Ровно это я ищу, когда провожу «Аудит до денег»: где бизнес теряет клиентов, о которых даже не знает, и как он выглядит на фоне пяти конкурентов - на цифрах, до любых договорённостей.

Подписаться и получить разбор: https://t.me/janeprovideo

Как поставить сертификат Минцифры в системное хранилище?

Коротко: на сервере с Debian или Ubuntu это три команды. Скачиваете два файла сертификата Минцифры (корневой и промежуточный) в специальную папку, запускаете update-ca-certificates и ждёте строку вида «2 added». После этого системное хранилище доверенных сертификатов знает про Минцифры, и всё, что читает системный список, перестаёт ругаться на SSL.

Системное хранилище - это общий список доверенных «паспортных столов» для всей операционной системы. На Debian и Ubuntu своя папка для добавленных вручную сертификатов и одна команда, которая пересобирает список.

Порядок такой:

  1. Перейдите в папку для доверенных сертификатов на сервере.
  2. Скачайте оба файла Минцифры - корневой и промежуточный - прямо туда.
  3. Пересоберите системный список одной командой и дождитесь подтверждения.
bash
cd /usr/local/share/ca-certificates/
wget https://gu-st.ru/content/lending/russian_trusted_root_ca_pem.crt
wget https://gu-st.ru/content/lending/russian_trusted_sub_ca_pem.crt
update-ca-certificates   # ждём строку вида "2 added"

Строка 2 added, 0 removed; done. в ответе - и есть подтверждение, что оба сертификата приняты. Тут работают два жёстких требования системы, о которых честно предупреждает документация:

«all certificates with a .crt extension found below /usr/local/share/ca-certificates are also included and implicitly trusted... Certificates must be in PEM format and have a .crt extension in order to be included by update-ca-certificates.» (Перевод: «Все сертификаты с расширением .crt из папки /usr/local/share/ca-certificates включаются в список и получают доверие... Чтобы попасть в сборку, сертификат должен быть в формате PEM и иметь расширение .crt».)

То есть если файл лежит не в той папке или без расширения .crt - команда его молча не подхватит, и вы будете гадать, почему не помогло.

Важно. Всё это делается на сервере, где реально работает бот, а не на вашем ноутбуке. Компьютер нужен только чтобы подключиться к серверу и ввести команды. Сертификат на вашем ноутбуке боту на сервере не поможет.

Почему requests и httpx падают даже после установки? (ловушка certifi)

Коротко: вы поставили сертификат в систему, а бот всё равно падает с той же ошибкой. Причина в библиотеках. requests и httpx не смотрят в системное хранилище - у них свой отдельный список доверенных сертификатов, пакет certifi, собранный по международному перечню без российских корней. Библиотеки на aiohttp читают системный список и чинятся сразу, а requests и httpx нужно лечить отдельно.

Вот здесь спотыкается большинство. Сертификат поставлен, update-ca-certificates отчитался «2 added», а бот на requests продолжает падать. Кажется, что установка не сработала. Она сработала - просто библиотека смотрит не туда.

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

«Requests uses certificates from the package certifi. This allows for users to update their trusted certificates without changing the version of Requests.» (Перевод: «Requests использует сертификаты из пакета certifi. Это позволяет обновлять доверенные сертификаты, не меняя версию самого Requests».)

Отсюда классический симптом, который сбивает с толку: на одном и том же сервере requests работает, а aiohttp падает, или наоборот. Люди месяцами не понимают, в чём дело. Вот заголовок реального обсуждения в трекере aiohttp:

«certificate verify failed: unable to get local issuer certificate. The requests library works fine though.» (Перевод: «Проверка сертификата не прошла: не удаётся найти издателя. При этом библиотека requests работает нормально».)

Разница именно в источнике доверия: aiohttp с настройками по умолчанию берёт системное хранилище, а requests и httpx - свой certifi. Держите под рукой карту, кого чем лечить.

БиблиотекаКуда смотрит за доверенными сертификатамиЧем лечить
aiohttp (настройки по умолчанию)системное хранилище ОСupdate-ca-certificates (раздел выше)
requestsсвой набор certifiдобавить корень в certifi или обновить сам certifi
httpxсвой набор certifiто же, что requests

Чтобы requests и httpx увидели Минцифру, добавьте оба сертификата в их набор certifi:

bash
CERTIFI=$(/usr/bin/python3 -c "import certifi; print(certifi.where())")
cat russian_trusted_root_ca_pem.crt russian_trusted_sub_ca_pem.crt >> "$CERTIFI"

Первая команда спрашивает у Python, где физически лежит файл со списком certifi, вторая - дописывает в конец этого файла оба сертификата Минцифры. После перезапуска бота requests и httpx начинают доверять российским сервисам.

Важно. Не поддавайтесь соблазну «просто отключить проверку» через verify=False. Так вы убираете саму защиту: канал перестаёт проверять, с кем разговаривает, и открывается для перехвата. Сама ошибка при этом никуда не девается. Документация Requests предупреждает об этом прямым текстом: «when verify is set to False, requests will accept any TLS certificate presented by the server... which will make your application vulnerable to man-in-the-middle (MitM) attacks» (перевод: «при verify=False requests примет любой сертификат от сервера, из-за чего приложение станет уязвимо к атаке посредника»). Правильный путь - поставить сертификат, а не выключить проверку.

Живой кейс: миграция консьержа с platform-api.max.ru на новый адрес

Коротко: у меня на сервере круглосуточно живёт автономный консьерж отеля - Python-бот, который отвечает гостям в ВКонтакте и в MAX и обращается к GigaChat. Себестоимость - около 20 000 рублей в год. Когда MAX объявил переезд на новый адрес, миграция коснулась в первую очередь именно таких ботов, как этот. Расскажу, что и в каком порядке я делала.

Это не пересказ чужой инструкции. Автономного консьержа для парк-отеля «Дубрава» я собрала и держу сама: он работает без выходных, отвечает за одну-три секунды в любое время суток и передаёт горячие заявки менеджеру, пока тот спит. Как я вообще собрала эту автоматизацию отеля без программиста, разбирала отдельно. Здесь важно, что этот бот стучится и в MAX, и в GigaChat - ровно те сервисы, у которых сертификат Минцифры и переезды адресов.

Когда MAX сменил адрес, разработчики объявили это открыто, с датами:

«до 19 июля 2026 необходимо перенаправить HTTP-запросы с домена platform-api.max.ru на platform-api2.max.ru... Передача токена через query-параметры больше не поддерживается - используйте заголовок Authorization... с 25 мая 2026 прекращается поддержка получения вебхуков по HTTP, а также самоподписных сертификатов.»

Дата стоит на 19 июля 2026 года - на момент, когда я это пишу. Но дата тут не главная героиня. Старый адрес просто выключат, и бот, который ходит по нему, замолчит - без ошибки заранее, в час X. Поэтому такие письма я отрабатываю сразу, пока всё работает и есть запас времени на спокойный откат, а не в ночь перед отключением. Что именно делать - зависит от того, как устроен бот.

Обновить библиотеку или править код руками?

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

Вариант А - обновить библиотеку. Многие боты MAX написаны на готовой библиотеке (например, maxapi для Python). В таком случае адрес, способ передачи токена и работа с сертификатом спрятаны внутри неё. Свежая версия уже знает и про новый домен, и про Минцифру. Значит, код бота трогать не нужно - достаточно аккуратно обновить библиотеку и записать, с какой версии вы уходите, чтобы был откат.

bash
/usr/bin/python3 -m pip show maxapi | grep Version   # какая версия стоит сейчас
/usr/bin/python3 -m pip freeze | grep -i maxapi      # записать - это точка отката
/usr/bin/python3 -m pip install "maxapi==1.2.1" --break-system-packages

Ставьте конкретную свежую версию, а не latest вслепую: так вы точно знаете, что установилось, и можете вернуться на записанную версию одной командой, если что-то пойдёт не так. Номер 1.2.1 здесь - пример актуального на момент написания; проверьте свежую версию библиотеки перед установкой.

Вариант Б - править код руками. Если бот шлёт запросы сам, без библиотеки-посредника, придётся внести три правки:

  1. Сменить домен запросов на platform-api2.max.ru.
  2. Передавать токен через заголовок Authorization, а не в адресе запроса (раньше часто клали в конец адреса, вроде ?access_token=... - этот способ больше не работает).
  3. Поставить сертификаты Минцифры на сервер - как в разделах выше, с учётом ловушки certifi.
Вариант А: обновить библиотекуВариант Б: править код руками
Когда подходитбот на готовой библиотекебот сам шлёт запросы
Что делаетеобновляете библиотеку до свежей версиименяете домен, токен в заголовок, ставите сертификаты
Рискминимальный, код не трогаетевыше, ручные правки
Откатвернуть записанную версию одной командойоткатывать правки в коде

Я почти всегда иду по первому пути. Обновить, а не переписать - меньше касаний кода, меньше поверхности для новой ошибки.

Что делать с ошибкой externally-managed-environment?

Коротко: на свежих Debian и Ubuntu команда pip install в системный Python падает с ошибкой externally-managed-environment. Система защищает свои пакеты от случайной поломки. Флаг --break-system-packages снимает запрет на одну установку, но включать его стоит осознанно. Чистый путь - виртуальное окружение venv, где этого запрета нет вовсе.

Свежие Debian, Ubuntu и Raspberry Pi специально блокируют установку пакетов в системный Python, чтобы вы случайно не сломали то, чем управляет сам пакетный менеджер системы. Отсюда и флаг из команды выше. Правило описано в стандарте языка, и там же - честное предупреждение про флаг:

«The installer should have a way for the user to override these rules, such as a command-line flag --break-system-packages... [it] should not be enabled by default and should carry some connotation that its use is risky.» (Перевод: «У установщика должен быть способ обойти эти правила, например флаг --break-system-packages... он не должен быть включён по умолчанию и должен нести оттенок того, что его использование рискованно».)

Практический вывод простой. Если бот уже стоит в системном Python - обновляете с флагом, как в варианте А, и это осознанный разовый шаг. Если бот живёт в отдельном виртуальном окружении (venv) - устанавливаете прямо в него, и никакой флаг не нужен: запрета там нет. Второй способ чище, и если будете собирать бота с нуля, я советую сразу венв.

Когда это повторится и как подготовиться заранее?

Коротко: это не разовая история про MAX. Та же процедура всплывает каждый раз, когда российский сервис объявляет переезд на новый домен или требование сертификата Минцифры, когда серверный код падает с CERTIFICATE_VERIFY_FAILED у GigaChat, банка или госсервиса, и когда партнёр меняет способ передачи токена. Симптом один, лечение похожее.

Три ситуации, в которых вы снова увидите эту ошибку:

  1. Российский сервис объявляет переезд на новый домен или вводит требование сертификата Минцифры. Так было с MAX, и так будет ещё не раз.
  2. Серверный код падает с CERTIFICATE_VERIFY_FAILED при обращении к GigaChat, банковскому сервису или госуслугам. Почти всегда причина одна - на сервере не хватает корневого сертификата Минцифры. GigaChat, например, говорит об этом прямо: «Для обмена сообщениями с GigaChat API нужен корневой сертификат Минцифры» (документация Сбера). Лечение - тот же корень Минцифры в нужное хранилище.
  3. Партнёр меняет способ авторизации - переносит токен из адреса запроса в заголовок или наоборот. Тогда правится способ передачи токена в коде.

И короткий чек-лист «не навреди», который экономит нервы:

  1. Делайте всё на сервере, где реально работает бот, а не на своём компьютере.
  2. Запишите текущую версию библиотеки до обновления - это ваша точка отката.
  3. Делайте в спокойный момент, а не перед наплывом клиентов, чтобы было время откатиться.
  4. Если бот работает на вебхуках (режим, когда сервис сам стучится на ваш сервер, а не бот его опрашивает), у MAX с конца мая 2026 года нужен HTTPS с сертификатом от доверенного центра - самоподписанный и обычный HTTP больше не примут.

Что это значит для владельца бизнеса?

Коротко: вам не нужно разбираться в certifi и удостоверяющих центрах. Вам нужно, чтобы бот отвечал клиенту 19 июля так же, как отвечал 18-го. Вся эта работа - пятнадцать минут на сервере, а не недельное внедрение и счёт от интегратора. И главное: если известно, где лежит сертификат и как его обновить, бот переживёт любой переезд без программиста в штате.

Здесь и прячется настоящая тема: зависимость от того, кто понимает вашу систему. Самый частый страх у тех, кто заказывал бота на стороне: подрядчик ушёл, а система осталась чёрным ящиком, который сломался при первом же переезде адреса, и никто не помнит, где вообще лежит этот сертификат. Тогда молчащий бот превращается в аврал и срочный поиск исполнителя.

Я смотрю на это иначе, потому что работаю изнутри бизнеса. Всё, что описано выше, - это пятнадцать минут понятных действий на сервере. Интегратор завёл бы под это тикет, недельное согласование и счёт. А по сути надо скачать два файла, дописать их в нужный список и перезапустить бота. Как и в истории про то, почему Яндекс Директ сливает бюджет: там всё держится на контроле и понимании системы, а сам инструмент вторичен.

Владельцу не нужно знать про certifi и цепочки доверия. Ему нужно, чтобы клиент, написавший ночью, получил ответ. certifi, удостоверяющие центры, транспорт - это сложное внутри. Снаружи должно остаться простое: бот отвечает, заявки не теряются, система переживает переезд сервиса без паники. Если вы только присматриваетесь к тому, с чего вообще начать наводить порядок с ИИ в бизнесе, я разбирала это пошагово в материале AI-маркетинг на практике: с чего начать.

Источники

Молчащий бот - это заявки, которые утекают незаметно, пока вы об этом не знаете. Если хотите увидеть на своих цифрах, где ещё бизнес теряет деньги и как он выглядит на фоне пяти конкурентов, начните с бесплатного «Аудита до денег».

Подписаться и получить разбор: https://t.me/janeprovideo

Статья была полезной?
Автор
Jane Kosykh
AI-маркетолог, архитектор AI-систем для бизнеса

Строю AI-системы и автоматизацию для бизнеса. 17 лет в маркетинге, последние 2 года - внутри бизнесов как AI-интегратор. Вижу где теряются деньги - закрываю это стабильными инструментами без программиста в штате.