Zum Inhalt springen
ecdsa.com
requests / urllib3 (Python)Python cryptography

Fehlermeldung

Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate

Auch ausgegeben als

  • requests.exceptions.SSLError: HTTPSConnectionPool(host='api.example.com', 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

Host, Port und URL-Pfad stammen aus deiner Anfrage. Der innerste Grund variiert („self-signed certificate in certificate chain“, „Hostname mismatch…“, „certificate has expired“), und die Zeile endet mit einer Quellcode-Position wie „(_ssl.c:1082)')))“.

requests / urllib3 (Python) — requests.exceptions.SSLError wrapping urllib3 MaxRetryError

Was der Fehler bedeutet

requests hat bei urllib3 eine Verbindung angefordert, im TLS-Handshake ist die Zertifikatsprüfung fehlgeschlagen, und urllib3 hat aufgegeben (bei der Standardeinstellung von requests ohne Wiederholungen schon nach dem ersten Versuch). Der aufschlussreiche Teil steht in den Klammern: Hier konnte OpenSSL den Aussteller nicht in dem CA-Bundle finden, das requests verwendet – standardmäßig ist das die Kopie der Mozilla-Root-Zertifikate aus certifi, nicht der Zertifikatsspeicher des Betriebssystems.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Richtiges Bundle mit verify= übergeben

    verify akzeptiert den Pfad zu einer CA-Bundle-Datei oder zu einem gehashten CA-Verzeichnis; Hostnamen- und Datumsprüfungen bleiben dabei aktiv.

    python
    import requests
    
    # A CA file (or a directory prepared with c_rehash) for this call
    requests.get("https://api.example.com/", verify="/etc/ssl/certs/ca-certificates.crt")
  2. 2.

    REQUESTS_CA_BUNDLE für den Prozess setzen

    Zeigt die Variable auf das System-Bundle (nachdem du deine CA dort installiert hast), vertraut jeder Aufruf von requests in diesem Prozess denselben Root-Zertifikaten wie curl und die Tools des Betriebssystems.

    bash
    # For every requests call in the process (also honoured: CURL_CA_BUNDLE)
    export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt   # Debian/Ubuntu system bundle
    python3 app.py
  3. 3.

    Trust Store des Betriebssystems verwenden

    Ein Aufruf von truststore.inject_into_ssl() beim Programmstart lässt requests über das Betriebssystem prüfen, sodass von der IT verteilte Root-Zertifikate funktionieren, ohne dass du Bundles pflegen musst.

    python
    # pip install truststore==0.10.5 — requests then verifies with the OS trust store
    import truststore
    truststore.inject_into_ssl()
    
    import requests
    requests.get("https://api.example.com/")
  4. 4.

    Eine Session einmal konfigurieren

    Setze in Anwendungen Session.verify auf ein Bundle, das die öffentlichen Root-Zertifikate sowie das Root-Zertifikat der Firma enthält, und verwende die Session wieder.

    python
    import requests
    
    session = requests.Session()
    session.verify = "/etc/ssl/private-ca/corp-ca-bundle.pem"   # public roots + company root
    session.get("https://api.example.com/")

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen