[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate は、接続先の証明書を発行した認証局を、そのツールが信頼していないときに出るエラーです。 社内プロキシ(TLSを検査するセキュリティ製品)を通る環境や、社内の認証局で作った証明書のサーバーに接続するときによく出ます。

いちばんの落とし穴は、ツールごとに見ている「信頼する認証局の一覧(証明書ストア)」が違うことです。同じPCで、curl は通るのに Python の requests だけ失敗する、ということが普通に起きます。

ツール 見ている証明書ストア 直し方(代表)
Python requests certifi(パッケージに同梱の一覧) REQUESTS_CA_BUNDLE、verify=
Python urllib・標準の ssl OSの証明書ストア(OpenSSL) OSに入れる、SSL_CERT_FILE
pip 24.2 以降 OSのストア+certifi(truststore) OSに入れる、--cert、PIP_CERT
pip 24.1 まで certifi(Ubuntu などが配布する pip は OS のストアを使うよう変更されていることがある) --cert、PIP_CERT
curl OSの証明書ストア OSに入れる、--cacert
Node.js Node に同梱の一覧 NODE_EXTRA_CA_CERTS、--use-system-ca
git OSの証明書ストア OSに入れる、http.sslCAInfo

この記事では、社内の認証局で作った証明書のサーバーを用意し、6つのツールで同じエラーを起こして、直し方を1つずつ確かめました。証明書の検証を無効にする書き方(verify=False・-k・NODE_TLS_REJECT_UNAUTHORIZED=0)は載せていません。 通信の盗み見や改ざんを防げなくなるためです。

確認環境:Ubuntu 24.04、Python 3.11・3.12・3.13、requests 2.34.2、pip 24.0 と 26.2.1、curl 8.5.0、Node.js 22.22.2、git(確認日 2026年10月10日)。テスト用の認証局(ルート→中間→サーバー)を作り、HTTPS サーバーで確認しました。Java の場合は「PKIX path building failed」という別の表示になります(関連記事を参照)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「CERTIFICATE_VERIFY_FAILEDの直し方|pip・Node」

6つのツールで出たエラー

社内の認証局の証明書をどこにも入れていない状態で、同じ URL に接続しました。

== python urllib
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1016)>
== python requests
requests.exceptions.SSLError: HTTPSConnectionPool(host='localhost', port=8443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1016)')))
== pip
WARNING: Retrying (Retry(total=4, ...)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1016)'))': /simple/requests/
== curl
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.se/docs/sslcerts.html
== node
fetch failed / UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate
== git
fatal: unable to access 'https://localhost:8443/repo.git/': server certificate verification failed. CAfile: none CRLfile: none

表示は違っても、原因は同じ「発行元の認証局を信頼していない」です。unable to get local issuer certificate は「発行元(issuer)の証明書が、手元(local)の一覧に無い」という意味です。

手順1:信頼する証明書(ルート証明書)を手に入れる

まず、信頼させたい認証局の証明書(PEM 形式、-----BEGIN CERTIFICATE----- で始まるテキスト)を用意します。

状況 入手のしかた
社内プロキシ・セキュリティ製品 情報システム部門から配布されているものを使う。Windows は「証明書の管理」の「信頼されたルート証明機関」から、Base64 形式(.cer)でエクスポートできる
社内の認証局で作ったサーバー サーバーの管理者から、ルート証明書(と中間証明書)をもらう
自分で確かめたい openssl s_client -connect ホスト:443 -showcerts で、サーバーが送る証明書の鎖を表示する。最後の証明書の発行元(i:)が、信頼させたい認証局

信頼させるのは、接続先のサーバー証明書ではなく、発行元の認証局(ルート証明書)です。この記事では、そのファイルを corp-root.crt と呼びます。

手順2:OSの証明書ストアに入れる(まとめて効く)

OS に入れると、OSのストアを見るツール(curl・git・urllib・pip 24.2 以降)にまとめて効きます。

# Ubuntu・Debian
sudo cp corp-root.crt /usr/local/share/ca-certificates/corp-root.crt
sudo update-ca-certificates
OS 入れ方
Ubuntu・Debian 上のコマンド(拡張子は .crt)
RHEL・Amazon Linux /etc/pki/ca-trust/source/anchors/ に置いて sudo update-ca-trust
macOS キーチェーンアクセスで「システム」に追加し、「常に信頼」にする
Windows 証明書をダブルクリック →「証明書のインストール」→「信頼されたルート証明機関」

OS に入れたあと、同じツールで試した結果です(確認環境の pip は Ubuntu の環境で動いていて、OS に入れた時点で通りました)。

urllib:   b'OK\n'
curl:     OK
git:      (証明書のエラーは消えた)
requests: requests.exceptions.SSLError: ... CERTIFICATE_VERIFY_FAILED ...   ← まだ失敗
node:     fetch failed UNABLE_TO_GET_ISSUER_CERT_LOCALLY                    ← まだ失敗

requests と Node.js は、OS のストアを見ていないので直りません。 ここが「curl は通るのに Python だけ失敗する」の正体です。手順3で、ツールごとに指定します。

手順3:ツールごとに指定する

OS のストアから証明書を外した状態で、ツールごとの指定だけで直ることを確かめました。

ツール 指定のしかた 結果
requests 環境変数 REQUESTS_CA_BUNDLE=/path/corp-root.crt、または requests.get(url, verify="/path/corp-root.crt") OK
urllib・ssl 環境変数 SSL_CERT_FILE=/path/corp-root.crt OK
pip pip install --cert /path/corp-root.crt ...、または環境変数 PIP_CERT OK
curl curl --cacert /path/corp-root.crt ... OK
Node.js 環境変数 NODE_EXTRA_CA_CERTS=/path/corp-root.crt OK
git git config --global http.sslCAInfo /path/corp-root.crt OK

Python(requests)

import requests
r = requests.get("https://internal.example.com/api", verify="/path/corp-root.crt")

REQUESTS_CA_BUNDLE や verify= に社内の証明書だけを指定すると、今度は公開のサイト(GitHub など)が信頼できなくなります。社内と社外の両方に接続するなら、certifi の一覧に社内の証明書を足したファイルを作って指定するか、次の truststore を使います。

cat "$(python -m certifi)" corp-root.crt > ca-bundle-with-corp.pem
export REQUESTS_CA_BUNDLE=$PWD/ca-bundle-with-corp.pem

Python(truststore で OS のストアを使わせる)

truststore パッケージ(Python 3.10 以降)を使うと、requests にも OS のストアを使わせられます。OS に社内の証明書が入っていれば、ツールごとの指定が要りません。

import truststore
truststore.inject_into_ssl()   # 以降の requests・urllib3 が OS のストアを使う
import requests

pip は 24.2 から、この truststore を使って OS のストアと certifi の両方を見るようになりました。pip 24.0 では --cert が要った環境でも、pip を新しくするだけで直ることがあります。

python -m pip install -U pip

Node.js

Node.js は、本体に組み込まれた認証局の一覧を使うため、OS に入れても効きません。

export NODE_EXTRA_CA_CERTS=/path/corp-root.crt   # 組み込みの一覧に「追加」される
node app.js

確認環境の Node.js 22.22 では、OS のストアを使わせる --use-system-ca オプションと、環境変数 NODE_USE_SYSTEM_CA=1 も使えました(OS に証明書を入れた状態で OK)。npm も Node.js で動くので、NODE_EXTRA_CA_CERTS が効きます(npm だけに指定するなら npm config set cafile /path/corp-root.crt)。

Python 3.13 だけ「Missing Authority Key Identifier」で失敗する

社内の証明書を正しく入れたのに、Python 3.13 にしたら急に失敗することがあります。同じ証明書・同じサーバーで、Python のバージョンだけを変えました。

python3.11: b'OK\n'
python3.12: b'OK\n'
python3.13: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier (_ssl.c:1032)>

Python 3.13 から、ssl.create_default_context() が証明書の形式を厳しく確かめる設定(VERIFY_X509_STRICT)を既定にしたためです。社内の認証局やプロキシ製品が作った証明書に、規格(RFC 5280)で求められる拡張項目(Authority Key Identifier など)が入っていないと、このエラーになります。

直し方 内容
証明書を作り直す(推奨) 認証局の証明書に subjectKeyIdentifier・keyUsage、サーバー証明書に authorityKeyIdentifier を入れて発行し直す。確認環境では、拡張項目を入れて作り直した証明書は Python 3.13 でも OK になった
管理者に依頼する プロキシ製品の証明書なら、製品側の設定や更新で直ることがある
一時的に厳格な確認を外す 公式ドキュメントにある方法。推奨はされていない
import ssl
ctx = ssl.create_default_context()
ctx.verify_flags &= ~ssl.VERIFY_X509_STRICT   # 一時的な回避。証明書を直すまで

証明書に何が入っているかは、次のコマンドで確認できます(No extensions in certificate なら拡張項目が無い)。

openssl x509 -in corp-root.crt -noout -ext authorityKeyIdentifier,subjectKeyIdentifier,keyUsage

証明書の検証を無効にしない

検索すると、verify=False、curl -k、NODE_TLS_REJECT_UNAUTHORIZED=0、pip --trusted-host でエラーを消す方法が見つかります。これらは偽のサーバーにも接続してしまう状態にするもので、社内プロキシの環境でも、プロキシを装った通信を見分けられなくなります。上の手順で、正しい証明書を信頼させる方法をとります。

確認の手順(チェックリスト)

順番 確認すること 方法
1 発行元の認証局はどれか openssl s_client -connect ホスト:443 -showcerts の最後の i:
2 その認証局の証明書(PEM)を持っているか 情報システム部門・サーバー管理者から入手
3 失敗しているツールは、どのストアを見るか 冒頭の表(requests・Node.js は OS のストアを見ない)
4 OS に入れたか、ツールごとに指定したか 手順2・手順3
5 社内だけの一覧を指定して、社外が失敗していないか certifi+社内の証明書をまとめたファイルにする
6 Python 3.13 で Missing Authority Key Identifier 証明書の拡張項目を確認する

よくある質問

Q. curl やブラウザでは通るのに、Python だけ失敗します。 A. requests は OS のストアではなく certifi の一覧を使うためです。REQUESTS_CA_BUNDLE を指定するか、truststore を使います。

Q. 社内では通るのに、自宅(VPNなし)では社外のサイトが失敗します。 A. REQUESTS_CA_BUNDLE などに社内の証明書だけを指定していると、プロキシを通らない環境では公開の認証局を信頼できなくなります。certifi の一覧と社内の証明書をまとめたファイルを指定します。

Q. Docker のコンテナの中で出ます。 A. コンテナは、ホストの OS とは別の証明書ストアを持っています。Dockerfile で証明書をコピーし、update-ca-certificates を実行します。Python や Node.js の環境変数も、コンテナの中で設定します。

Q. Java でも同じエラーが出ますか。 A. Java では「PKIX path building failed」という表示になり、Java 専用の証明書ストア(cacerts)に入れる必要があります。

まとめ

  • 原因は「発行元の認証局を信頼していない」。表示はツールごとに違う
  • ツールごとに見ているストアが違う:requests は certifi、Node.js は組み込み、curl・git・urllib は OS
  • OS に入れる+ツールごとに指定の2段で直す。requests は REQUESTS_CA_BUNDLE、Node.js は NODE_EXTRA_CA_CERTS
  • pip は 24.2 から OS のストアも見る。pip を新しくするだけで直ることがある
  • Python 3.13 の Missing Authority Key Identifier は証明書の形式の問題。証明書を作り直すのが本来の直し方
  • 検証を無効にする書き方は使わない

参考・出典

確認日はいずれも 2026年10月10日です。

  • Python 3.13 ドキュメント「What's New In Python 3.13(ssl)」:https://docs.python.org/3/whatsnew/3.13.html
  • pip ドキュメント「HTTPS Certificates」:https://pip.pypa.io/en/stable/topics/https-certificates/

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「CERTIFICATE_VERIFY_FAILEDの直し方|pip・Node」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?