El error SSL certificate problem: unable to get local issuer certificate (o sus variantes) es uno de los dolores de cabeza más comunes en desarrollo. Significa que la herramienta no puede verificar la cadena de certificados del servidor, generalmente porque los certificados raíz de las CA en tu sistema están desactualizados o faltan.
Esta guía cubre soluciones adecuadas, no solo los atajos -k / --insecure que desactivan la seguridad.
La causa raíz
Tus herramientas verifican los certificados SSL contra un paquete de CA (CA bundle): un archivo que contiene los certificados raíz de confianza. Cuando este paquete está desactualizado, falta, o el servidor tiene una cadena incompleta, la verificación falla.
Your tool → "Is this certificate signed by a CA I trust?"
CA bundle → "I don't have that CA's root certificate"
→ ERROR: unable to get local issuer certificate
curl
Error
curl: (60) SSL certificate problem: unable to get local issuer certificate
Solución 1: Actualizar certificados CA (solución correcta)
# Debian/Ubuntu
sudo apt update && sudo apt install ca-certificates
sudo update-ca-certificates
# CentOS/RHEL
sudo yum update ca-certificates
# macOS (Homebrew curl)
brew install ca-certificates
Solución 2: Especificar la ruta del paquete CA
curl --cacert /etc/ssl/certs/ca-certificates.crt https://example.com
Solución 3: Establecer variable de entorno
export CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
No hagas esto (a menos que sea para pruebas)
curl -k https://example.com # Disables ALL certificate verification
Git
Error
fatal: unable to access 'https://...': SSL certificate problem: unable to get local issuer certificate
Solución 1: Actualizar certificados CA (igual que curl)
sudo apt update && sudo apt install ca-certificates
Solución 2: Apuntar Git al paquete CA correcto
git config --global http.sslCAInfo /etc/ssl/certs/ca-certificates.crt
Solución 3: En Windows (Git for Windows)
Git for Windows incluye sus propios certificados CA. Actualiza Git a la última versión, o:
git config --global http.sslBackend schannel
Esto le indica a Git que use el almacén de certificados integrado de Windows en lugar del incluido con Git.
No hagas esto en producción
git config --global http.sslVerify false # Disables ALL SSL verification for Git
Python (requests / pip)
Error (requests)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]
Error (pip)
pip install ... Could not fetch URL https://...: connection error: [SSL: CERTIFICATE_VERIFY_FAILED]
Solución 1: Actualizar certifi (paquete CA de Python)
pip install --upgrade certifi
La librería requests de Python usa el paquete certifi para certificados CA, no el almacén del sistema.
Solución 2: Apuntar al paquete CA del sistema
import requests
response = requests.get('https://example.com', verify='/etc/ssl/certs/ca-certificates.crt')
O variable de entorno:
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
Solución 3: Python en macOS (problema común)
Python en macOS frecuentemente tiene un almacén de certificados vacío después de la instalación. Ejecuta:
# Find your Python install
python3 -c "import ssl; print(ssl.get_default_verify_paths())"
# Install certificates (macOS Python from python.org)
/Applications/Python\ 3.x/Install\ Certificates.command
Solución para pip específicamente
pip install --upgrade pip
pip config set global.cert /etc/ssl/certs/ca-certificates.crt
Node.js
Error
Error: unable to get local issuer certificate
code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY'
Solución 1: Establecer NODE_EXTRA_CA_CERTS
export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
Esto añade CAs adicionales sin reemplazar el paquete integrado de Node.
Solución 2: Para certificados autofirmados en desarrollo
// Only for development — adds a specific CA
const https = require('https');
const fs = require('fs');
const agent = new https.Agent({
ca: fs.readFileSync('/path/to/custom-ca.pem'),
});
fetch('https://internal-service.local', { agent });
No hagas esto en producción
export NODE_TLS_REJECT_UNAUTHORIZED=0 # Disables ALL SSL verification
Proxy corporativo / entornos empresariales
Muchas redes corporativas usan un proxy de inspección TLS que vuelve a firmar el tráfico con una CA interna. Tus herramientas no confían en esta CA interna.
Solución: Obtén el certificado de la CA corporativa de tu departamento de TI y añádelo:
# System-wide (Debian/Ubuntu)
sudo cp corporate-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
# Python
export REQUESTS_CA_BUNDLE=/path/to/corporate-ca-bundle.pem
# Node.js
export NODE_EXTRA_CA_CERTS=/path/to/corporate-ca.pem
# Git
git config --global http.sslCAInfo /path/to/corporate-ca-bundle.pem
Contenedores Docker
Las imágenes Docker frecuentemente tienen paquetes CA desactualizados. Solución:
# Debian-based
RUN apt-get update && apt-get install -y ca-certificates && update-ca-certificates
# Alpine
RUN apk add --no-cache ca-certificates
Diagnóstico rápido
# Test if the SSL connection works with openssl
openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>/dev/null | grep "Verify return code"
# "0 (ok)" = chain is fine, your tool's CA bundle is the problem
# "21 (unable to verify)" = server's chain is incomplete
# Check what CA bundle your system uses
python3 -c "import certifi; print(certifi.where())"
curl-config --ca 2>/dev/null || echo "Check /etc/ssl/certs/"
Preguntas frecuentes
¿Por qué funciona en mi navegador pero no en curl/Python?
Los navegadores mantienen su propio almacén de CA (actualizado con el navegador). Las herramientas CLI usan el paquete CA del sistema o el propio (Python usa certifi, Git for Windows incluye el suyo). Si el paquete del sistema está desactualizado, las herramientas CLI fallan mientras los navegadores funcionan bien.
¿Es seguro desactivar la verificación SSL?
Para pruebas rápidas: sí, si entiendes que no estás verificando la identidad del servidor. Para código en producción o CI/CD: nunca. Desactivar la verificación te expone a ataques de intermediario (man-in-the-middle). Siempre soluciona la causa raíz (actualizar el paquete CA o corregir la cadena del servidor).
El certificado del servidor está bien pero sigo recibiendo errores
Verifica si tu herramienta está pasando por un proxy que vuelve a firmar el tráfico. Las redes corporativas, algunas VPN y el software antivirus hacen esto. La CA del proxy no está en el almacén de confianza de tu herramienta.