Zum Inhalt springen
ecdsa.com
Python ssl module (OpenSSL)Python cryptography

Fehlermeldung

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

Auch ausgegeben als

  • ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate

Python hängt die Position im C-Quellcode an, etwa „(_ssl.c:1082)“; die Zahl ändert sich mit der Python-Version und ist für die Diagnose bedeutungslos. urllib verpackt den Fehler als „<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] …>“, requests und urllib3 als „Max retries exceeded … (Caused by SSLError(…))“.

Python ssl module (OpenSSL) — ssl.SSLCertVerificationError, X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY (20)

Was der Fehler bedeutet

Das Modul ssl von Python hat OpenSSL beauftragt, das Zertifikat des Servers zu prüfen, und OpenSSL konnte den Aussteller des letzten Zertifikats der Kette nicht unter den CA-Zertifikaten finden, die dieser SSLContext geladen hat. Der Server ist nicht unbedingt falsch konfiguriert: Oft verwendet dieses Python einfach ein anderes (oder leeres) CA-Bundle als dein Browser oder dein Betriebssystem.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Builds von python.org unter macOS: Install Certificates.command ausführen

    Das Skript installiert certifi und verlinkt es als Bundle für das OpenSSL dieses Python. Nach der Installation einer weiteren Python-Version muss es erneut ausgeführt werden.

    bash
    # macOS, python.org installer: run once per installed Python version
    "/Applications/Python 3.14/Install Certificates.command"
  2. 2.

    Mit truststore den Trust Store des Betriebssystems verwenden

    truststore lässt ssl.SSLContext über das Betriebssystem prüfen (Schlüsselbund unter macOS, Windows-Zertifikatsspeicher, System-Bundle unter Linux), sodass von deiner IT verteilte Root-Zertifikate auch in Python funktionieren. Es deckt außerdem urllib3, requests und pip ab; pip verwendet es seit pip 24.2 standardmäßig.

    python
    # pip install truststore==0.10.5  — verify with the OS trust store (Keychain, Windows store, Linux bundle)
    import truststore
    truststore.inject_into_ssl()   # call once at start-up, before creating connections
    
    import urllib.request
    urllib.request.urlopen("https://api.example.com/")
  3. 3.

    CA für einen Client explizit laden

    Übergib cafile (oder cadata) an ssl.create_default_context(), wenn Code mit einem privaten Dienst kommuniziert. Der Kontext prüft weiterhin Hostnamen und Gültigkeitszeiträume.

    python
    import ssl, urllib.request
    
    ctx = ssl.create_default_context(cafile="/etc/ssl/private-ca/corp-root-ca.pem")
    urllib.request.urlopen("https://api.example.com/", context=ctx)
  4. 4.

    Standardpfad des Bundles prüfen und setzen

    ssl.get_default_verify_paths() zeigt, welche Datei und welches Verzeichnis OpenSSL verwendet. Mit SSL_CERT_FILE und SSL_CERT_DIR überschreibst du beide für den Prozess; lass die Variablen auf ein Bundle zeigen, das sowohl öffentliche Root-Zertifikate als auch deine CA enthält.

    bash
    # Where does this Python look by default?
    python3 -c "import ssl; print(ssl.get_default_verify_paths())"
    # Point OpenSSL-based clients at a bundle that includes your CA
    export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
  5. 5.

    Auf dem Server: vollständige Kette ausliefern

    Enthält der Handshake nur ein Zertifikat und ist dessen Aussteller eine öffentliche Zwischen-CA, konfiguriere den Server mit der Full-Chain-Datei.

    bash
    # Server side: 1 certificate in the handshake = intermediate missing
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | grep -c 'BEGIN CERTIFICATE'

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen