本文へスキップ
ecdsa.com
Python urllib.requestPython の cryptography

エラーメッセージ

<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate

別の表記

  • urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate

山括弧の中のテキストは元になった ssl のエラーで、状況によって異なります(「self-signed certificate in certificate chain」「certificate has expired」など)。Python はソースの位置と「>」でこれを閉じます。例:「(_ssl.c:1082)>」。

Python urllib.request — urllib.error.URLError wrapping ssl.SSLCertVerificationError

このエラーの意味

urllib.request.urlopen() はあらゆる接続の問題を URLError でラップするため、TLS の失敗は「<urlopen error …>」の中に現れます。www.python.org を含むすべての公開サイトでこのエラーが起きる場合、その Python プロセスには使用できる CA 証明書がまったくありません。典型的なのは macOS の python.org 版インストーラーで、同梱の OpenSSL は「Install Certificates.command」を実行するまでキーチェーンを読み込みません。

発生する理由

修正方法

  1. 1.

    macOS:Install Certificates.command を実行する

    python.org の Python のバージョンごとに、Finder またはターミナルからこのスクリプトを実行し、その後でデフォルトの CA ファイルのパスが存在することを確認してください。

    bash
    # macOS, python.org installer (one script per installed version)
    "/Applications/Python 3.14/Install Certificates.command"
    python3 -c "import ssl; print(ssl.get_default_verify_paths().openssl_cafile)"
  2. 2.

    certifi から作成したコンテキストを渡す

    どこでも動作しなければならないスクリプトでは、certifi.where() から明示的に SSL コンテキストを作成してください。ルートが最新の状態に保たれるよう、certifi を更新し続けてください。

    python
    # Explicit, portable: use certifi's Mozilla bundle for this request
    # pip install certifi
    import certifi, ssl, urllib.request
    
    ctx = ssl.create_default_context(cafile=certifi.where())
    urllib.request.urlopen("https://www.python.org/", context=ctx)
  3. 3.

    または OS のトラストストアを使う

    truststore.inject_into_ssl() を呼び出すと、urllib、http.client、ssl を基盤とするライブラリが OS を通じて検証するようになり、IT 部門が配布した会社のルートも使われます。

    python
    # Or verify with the operating system's store (macOS Keychain, Windows, Linux bundle)
    # pip install truststore==0.10.5
    import truststore
    truststore.inject_into_ssl()
  4. 4.

    環境変数による上書きを確認する

    SSL_CERT_FILE と SSL_CERT_DIR が必要なルートを含まないファイルを指している場合は、これらの設定を解除してください。

    bash
    env | grep -E '^SSL_CERT_(FILE|DIR)='
    python3 -c "import ssl; print(ssl.get_default_verify_paths())"

関連するエラー

署名エラーデータベースをすべて見る