Message d’erreur
<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate
Également affiché sous la forme
- urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate
Le texte entre les chevrons est l’erreur ssl sous-jacente et varie (« self-signed certificate in certificate chain », « certificate has expired », …). Python le termine par un emplacement dans le code source et « > », par exemple « (_ssl.c:1082)> ».
Python urllib.request — urllib.error.URLError wrapping ssl.SSLCertVerificationError
Ce que cela signifie
urllib.request.urlopen() enveloppe tout problème de connexion dans une URLError : l’échec TLS apparaît donc dans « <urlopen error …> ». Lorsque cela se produit pour tous les sites publics, y compris www.python.org, le processus Python n’a aucun certificat d’AC utilisable. Le cas classique est l’installateur python.org sous macOS, dont l’OpenSSL intégré ne lit pas le trousseau tant que « Install Certificates.command » n’a pas été exécuté.
Pourquoi cela se produit
Python de python.org sous macOS sans ses certificats
fréquenteL’installateur fournit OpenSSL avec un magasin de confiance vide et un script d’aide, « Install Certificates.command », qui installe certifi et le lie. Si vous ne l’exécutez pas (ou si vous installez plus tard une nouvelle version mineure), urlopen reste incapable de vérifier quoi que ce soit.
Une image minimale ou un build personnalisé de Python sans fichier d’AC
occasionnelleUn Python compilé depuis les sources ou copié dans une image scratch ou distroless cherche le fichier d’AC à l’emplacement par défaut d’OpenSSL, qui n’existe pas dans ces images.
Un proxy d’inspection TLS
occasionnelleSi seuls certains sites échouent, ou si les échecs ont commencé sur un réseau d’entreprise, la cause probable est une racine de proxy à laquelle ce Python ne fait pas confiance.
SSL_CERT_FILE ou SSL_CERT_DIR pointe vers le mauvais emplacement
rareCes variables remplacent les emplacements par défaut pour tout le processus ; un fichier vide ou sans rapport fait échouer toutes les vérifications.
Comment corriger l’erreur
- 1.
macOS : exécuter Install Certificates.command
Exécutez-le depuis le Finder ou le terminal pour chaque version de Python de python.org, puis vérifiez que le chemin du fichier d’AC par défaut existe.
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.
Passer un contexte construit à partir de certifi
Pour les scripts qui doivent fonctionner partout, construisez explicitement le contexte SSL à partir de certifi.where() ; maintenez certifi à jour pour que ses racines restent actuelles.
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.
Ou utiliser le magasin de confiance du système d’exploitation
truststore.inject_into_ssl() fait vérifier urllib, http.client et les bibliothèques construites sur ssl via le système d’exploitation, y compris avec les racines d’entreprise déployées par le service informatique.
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.
Vérifier les remplacements définis dans l’environnement
Retirez SSL_CERT_FILE et SSL_CERT_DIR de l’environnement s’ils pointent vers des fichiers qui ne contiennent pas les racines nécessaires.
bash env | grep -E '^SSL_CERT_(FILE|DIR)=' python3 -c "import ssl; print(ssl.get_default_verify_paths())"