Сообщение об ошибке
There was a problem confirming the ssl certificate: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
Также выводится как
- Could not fetch URL https://pypi.example.com/simple/requests/: There was a problem confirming the ssl certificate: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate
pip выводит её в виде «Could not fetch URL <url>: There was a problem confirming the ssl certificate: … - skipping» после нескольких строк «WARNING: Retrying (Retry(total=…)) after connection broken by 'SSLError(…)'». URL и итоговая причина бывают разными.
pip — index or find-links URL over HTTPS (pip 24.2+ verifies with truststore by default)
Что это означает
pip не смог проверить TLS-сертификат индекса пакетов (или URL из find-links), поэтому пропустил эту страницу и обычно завершается сообщением «Could not find a version that satisfies the requirement». Причина после двоеточия — результат проверки OpenSSL. Начиная с pip 24.2, pip проверяет сертификаты по хранилищу доверенных сертификатов операционной системы через truststore, так что либо CA нет в хранилище ОС, либо в настройках pip указан другой пакет сертификатов.
Почему это происходит
Частный индекс (Artifactory, Nexus, devpi) с корпоративным сертификатом
частоВнутренние зеркала пакетов используют сертификаты корпоративного CA, который есть на управляемых ноутбуках, но отсутствует в образах CI, контейнерах и только что созданных виртуальных машинах.
Прокси с инспекцией TLS перед pypi.org
частоВ корпоративных сетях прокси переподписывает сертификаты pypi.org и files.pythonhosted.org. Если корневого сертификата прокси нет в хранилище доверенных сертификатов, которое использует pip, любая установка завершается ошибкой.
pip настроен использовать certifi вместо хранилища ОС
иногдаЕсли указан --use-deprecated=legacy-certs, явно задан параметр cert, указывающий на certifi, или pip работает на Python 3.9 и более ранних версиях (где truststore недоступен), корневые сертификаты, добавленные в хранилище ОС, не используются.
Старый pip, поставляемый вместе с Python
иногдаpip до версии 24.2 всегда использовал встроенный в него пакет сертификатов certifi. Многие базовые образы и виртуальные окружения до сих пор поставляются с такими версиями.
Как исправить
- 1.
Установите CA в хранилище доверенных сертификатов ОС
С pip 24.2+ на Python 3.10+ корневые сертификаты из системного хранилища (или из Keychain / хранилища Windows) считаются доверенными автоматически. Если pip старее, обновите его.
bash # pip >= 24.2 uses the OS trust store (truststore): add the CA there sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt sudo update-ca-certificates python3 -m pip --version # upgrade pip itself if it is older than 24.2 - 2.
Явно передайте pip пакет сертификатов CA
global.cert в конфигурации pip, PIP_CERT или --cert заставляют pip проверять сертификаты по этому файлу. Если pip обращается и к pypi.org, включите в файл также публичные корневые сертификаты.
bash # A CA bundle for pip only (one of these): python3 -m pip config set global.cert /etc/ssl/private-ca/corp-ca-bundle.pem export PIP_CERT=/etc/ssl/private-ca/corp-ca-bundle.pem python3 -m pip install --cert /etc/ssl/private-ca/corp-ca-bundle.pem requests - 3.
Настройте частный индекс один раз
Пропишите index-url и cert в pip.conf (или pip.ini), чтобы их использовал каждый запуск pip, в том числе внутри инструментов сборки.
ini # pip.conf (Linux: ~/.config/pip/pip.conf, Windows: %APPDATA%\pip\pip.ini) [global] index-url = https://pypi.example.com/simple/ cert = /etc/ssl/private-ca/corp-ca-bundle.pem - 4.
Временная диагностика: --trusted-host
--trusted-host отключает проверку сертификата для этого хоста и разрешает pip обращаться к нему по обычному HTTP. Это подтверждает диагноз, но всё, что скачано таким способом, могли подменить по пути; не оставляйте этот параметр в конфигурации.
bash # Temporary diagnostic only: --trusted-host disables certificate checks for that host python3 -m pip download --no-deps -d /tmp/dl --index-url https://pypi.example.com/simple/ \ --trusted-host pypi.example.com requests