« unable to get local issuer certificate » : trouver et corriger l’intermédiaire manquant

La page se charge sans problème dans le navigateur, mais curl, un script ou une application Java refusent la connexion. Dans la plupart des cas, il manque un certificat intermédiaire sur le serveur.

Messages typiques

curl: (60) SSL certificate problem: unable to get local issuer certificate
git:  SSL certificate problem: unable to get local issuer certificate
Python: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate
Node:   Error: unable to get local issuer certificate (UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
Java:   PKIX path building failed: unable to find valid certification path to requested target

Tous signifient la même chose : à partir du certificat serveur, le client ne parvient pas à construire une chaîne jusqu’à une AC racine de confiance.

Les navigateurs sont indulgents. S’il manque un intermédiaire, ils le téléchargent via l’adresse AIA du certificat ou le prennent dans leur cache parce qu’ils l’ont vu sur un autre site. curl, Python, Java, Git et la plupart des applis ne le font pas. Qu’un site fonctionne dans le navigateur ne prouve donc pas que la chaîne est complète.

Trois causes possibles

1. Le serveur n’envoie pas la chaîne complète (cause la plus fréquente)

Seul le certificat serveur a été configuré, sans l’intermédiaire. Vérifie avec la vérification SSL ou en ligne de commande :

openssl s_client -connect www.exemple.fr:443 -servername www.exemple.fr -showcerts </dev/null

Si la sortie ne liste qu’un seul certificat (0 s:CN=www.exemple.fr), accompagné de verify error:num=20:unable to get local issuer certificate, l’intermédiaire manque.

2. Il manque l’AC racine au client

D’anciennes images Docker sans le paquet ca-certificates, une installation Java obsolète ou un vieux paquet certifi sous Python ne connaissent pas les AC racines récentes.

3. Un pare-feu intercepte TLS, ou il s’agit d’une AC interne

Beaucoup de proxys et pare-feu d’entreprise remplacent les certificats par les leurs, émis par une AC interne. Les navigateurs des postes de l’entreprise connaissent cette AC via les stratégies de groupe, mais pas les conteneurs Docker, Python ou Java. Il en va de même pour les serveurs avec des certificats de ta propre AC d’entreprise.

Solution côté serveur : envoyer la chaîne complète

# nginx : certificat + intermédiaire dans un fichier
ssl_certificate     /etc/ssl/exemple/fullchain.pem;
ssl_certificate_key /etc/ssl/exemple/server.key;

# Apache 2.4.8+ : la chaîne va dans SSLCertificateFile
SSLCertificateFile    /etc/ssl/exemple/fullchain.pem
SSLCertificateKeyFile /etc/ssl/exemple/server.key

# Let's Encrypt : utiliser fullchain.pem, pas cert.pem

Sous Windows/IIS, l’intermédiaire doit se trouver dans le magasin « Autorités de certification intermédiaires » de l’ordinateur. Le plus simple est d’importer un PFX contenant la chaîne. S’il te manque l’intermédiaire, le convertisseur de certificats complète la chaîne via AIA, et la vérification SSL la lui transmet directement avec « Compléter la chaîne dans le convertisseur ».

Solution côté client

# Debian/Ubuntu : mettre à jour les AC racines ou ajouter ta propre AC
apt install ca-certificates
cp racine-entreprise.crt /usr/local/share/ca-certificates/ && update-ca-certificates

# Python (requests)
pip install --upgrade certifi
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

# Java 9+
keytool -importcert -cacerts -alias racine-entreprise -file racine-entreprise.crt

Évite curl -k, verify=False ou NODE_TLS_REJECT_UNAUTHORIZED=0 comme solution permanente. La connexion reste chiffrée, mais n’est plus protégée contre les attaquants.

FAQ

Dois-je envoyer l’AC racine ?

Non. Le serveur envoie le certificat serveur et les intermédiaires. L’AC racine doit déjà être présente chez le client ; une racine envoyée est ignorée.

Comment savoir si c’est le serveur ou le client ?

Vérifie le serveur avec la vérification SSL. S’il indique une chaîne complète, le problème vient du client (racine manquante ou proxy d’entreprise). S’il signale un intermédiaire manquant, il faut corriger le serveur.

Pourquoi l’erreur n’apparaît-elle que dans Docker ?

Les images allégées comme alpine ou debian-slim ne contiennent souvent aucune AC racine. Installe le paquet ca-certificates dans le Dockerfile ou copie ton AC d’entreprise et exécute update-ca-certificates.