Todas las guías de despliegue Despliegue

Solucionar errores de certificado SSL en curl, Git, Python y Node.js

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.

Artículos relacionados

SSL y certificados 2026-05-07
La cadena de confianza de certificados explicada
Cómo los navegadores verifican certificados SSL a través de una cadena desde la CA raíz a la CA intermedia hasta tu certificado. Aprende por qué el orden de la cadena importa y cómo solucionar errores de «certificado no confiable».
SSL y certificados 2026-05-08
Certificados autofirmados vs firmados por CA
Los certificados autofirmados generan advertencias en el navegador. Los firmados por CA son confiables automáticamente. Aprende cuándo es apropiado cada uno, cómo crear ambos y por qué los certificados CA gratuitos hacen obsoletos los autofirmados en producción.
Despliegue 2026-05-08
HTTPS para localhost: certificados SSL para desarrollo local
Configura HTTPS confiable en localhost con mkcert, sin advertencias del navegador. Cubre configuración de mkcert, certificados autofirmados y por qué Let's Encrypt no puede emitir certificados para localhost.
SSL y certificados 2026-05-08
Hoja de referencia de comandos OpenSSL para certificados SSL
Referencia rápida de los comandos OpenSSL más comunes: verificar vencimiento de certificados, comprobar cadenas, generar claves, convertir formatos y depurar conexiones TLS.
Obtén un certificado SSL gratuito en tu navegador
Sin instalación, sin cuenta. Tu clave privada nunca sale de tu dispositivo.
Obtener certificado