Códigos de error de curl: Referencia completa
Cuando un comando curl falla, devuelve un código de salida numérico (también llamado código de error de curl) que identifica el tipo de error. Puedes verificar el código de salida de curl ejecutando echo $? inmediatamente después del comando curl (o $LASTEXITCODE en PowerShell). El código de salida 0 significa éxito; cualquier otro número indica un problema específico — desde fallos de resolución DNS y tiempos de espera de conexión hasta problemas con certificados SSL. Esta página es una referencia completa de los códigos de error de curl más comunes con explicaciones, causas y soluciones. Si estás trabajando con comandos curl en tu código, pégalos en curl2code para convertirlos al lenguaje de programación que prefieras.
Tabla de referencia rápida
Éxito. La operación se completó sin ningún error.
Protocolo no soportado. La URL usa un protocolo para el que curl no fue compilado.
URL mal formada. La sintaxis de la URL es inválida o no pudo ser analizada.
No se pudo resolver el proxy. El nombre de host del proxy especificado no pudo ser resuelto.
La búsqueda DNS falló — el nombre de host no pudo ser resuelto a una dirección IP.
La conexión TCP falló — el servidor está caído, el puerto está bloqueado o el firewall está rechazando conexiones.
Archivo parcial. La transferencia fue interrumpida y solo se recibió parte del archivo.
El servidor devolvió un error HTTP (4xx/5xx) y se usó el flag --fail.
Error de escritura. curl no pudo escribir los datos recibidos en disco (permiso denegado o disco lleno).
La operación excedió el tiempo máximo permitido (DNS, conexión o transferencia).
El handshake SSL/TLS falló — incompatibilidad de versión de protocolo o suite de cifrado.
No se pudo leer el archivo. Un archivo local referenciado en la solicitud no pudo ser abierto o leído.
Respuesta vacía del servidor. El servidor cerró la conexión sin enviar ningún dato.
La conexión fue restablecida — el servidor cortó la conexión durante la transferencia de datos.
La verificación del certificado SSL falló — expirado, autofirmado o paquete de CA desactualizado.
Problema con el certificado CA SSL. No se pudo leer o analizar el archivo de certificado CA especificado.
Error de flujo HTTP/2. Ocurrió un error de protocolo HTTP/2 a nivel de flujo durante la transferencia.
Error 6: No se pudo resolver el host
- Qué significa
- Tu terminal muestra
curl: (6) Could not resolve host. curl no pudo resolver el nombre de host a una dirección IP — la búsqueda DNS falló antes de que se intentara cualquier conexión. - Causas
- Las causas más comunes son: un error tipográfico en el nombre de host (por ejemplo,
curl https://apiexample.comen lugar deapi.example.com), problemas con el servidor DNS (tu DNS configurado está caído o inaccesible), sin conexión de red (Wi-Fi desconectado, VPN no conectada), o el dominio genuinamente no existe. - Cómo solucionarlo
- Primero, verifica que la URL sea correcta. Luego prueba la resolución DNS directamente:
nslookup api.example.comodig api.example.com. Si el DNS falla, prueba un servidor DNS diferente:curl --dns-servers 8.8.8.8 https://api.example.com. Revisa tu/etc/resolv.confo la configuración de red. Si estás detrás de una VPN corporativa, asegúrate de que el DNS interno pueda resolver el host.
$ curl https://api.exmple.com/usersError 7: Fallo al conectar
- Qué significa
- Tu terminal muestra
curl: (7) Failed to connect to host port: Connection refused. curl resolvió el nombre de host pero no pudo establecer una conexión TCP con el servidor — la conexión fue rechazada activamente o se agotó el tiempo a nivel TCP. - Causas
- Las causas comunes incluyen: el servidor está caído o no está ejecutándose, un firewall está bloqueando el puerto (revisa tanto el firewall local como el del servidor), el puerto es incorrecto (por ejemplo, el servicio corre en 8080 pero te estás conectando al 443), o la cola de conexiones del servidor está llena bajo alta carga.
- Cómo solucionarlo
- Verifica que el servidor esté ejecutándose:
ping api.example.comytelnet api.example.com 443. Comprueba si el puerto correcto está abierto:nmap -p 443 api.example.com. Desactiva temporalmente el firewall local para probar. Si usas Docker, asegúrate de que el puerto del contenedor esté publicado. Prueba con modo detallado:curl -v https://api.example.compara ver exactamente dónde falla la conexión.
$ curl https://localhost:8080/apiError 22: HTTP devolvió un error
- Qué significa
- Tu terminal muestra
curl: (22) The requested URL returned error. El servidor devolvió un código de estado HTTP de error (4xx o 5xx) y curl fue invocado con-fo--fail, lo que le indica a curl que trate los errores HTTP como fallos. - Causas
- El error es provocado por códigos de estado HTTP como 400 (Bad Request), 401 (Unauthorized), 403 (Forbidden), 404 (Not Found) o 500 (Internal Server Error) — pero solo cuando se usa
--fail. Sin--fail, curl sale con código 0 incluso en errores HTTP. Causas comunes: URL incorrecta, falta de autenticación, permisos insuficientes o errores del lado del servidor. - Cómo solucionarlo
- Ejecuta curl sin
--failpara ver el cuerpo completo de la respuesta — a menudo contiene el mensaje de error real. Verifica el código de estado HTTP:curl -w "%{http_code}" -o /dev/null -s URL. Para 401/403: verifica tu token de autenticación o clave de API. Para 404: revisa la ruta de la URL. Para 500: el problema está en el servidor.
$ curl --fail https://api.example.com/nonexistentError 28: Tiempo de operación agotado
- Qué significa
- Tu terminal muestra
curl: (28) Operation timed outocurl: (28) Connection timed out. La operación tardó más del tiempo permitido. Este es el error de curl más común — puede ocurrir durante la resolución DNS, la conexión TCP, el handshake SSL o la transferencia de datos. - Causas
- Las causas típicas incluyen: servidor lento o sobrecargado que no responde a tiempo, congestión de red o pérdida de paquetes, firewall descartando paquetes silenciosamente (sin rechazo, solo silencio), valores de timeout demasiado estrictos establecidos con
--connect-timeouto--max-time, o una mala configuración del proxy causando retrasos. - Cómo solucionarlo
- Aumenta el tiempo de espera:
curl --connect-timeout 30 --max-time 120 URL. Usa el modo detallado para ver dónde se detiene:curl -v URL. Prueba la latencia de red:ping api.example.comytraceroute api.example.com. Si estás detrás de un proxy, intenta omitirlo:curl --noproxy '*' URL. Para transferencias de archivos grandes, considera usar--retry 3con--retry-delay 5.
$ curl --connect-timeout 5 https://slow-api.example.com/dataError 35: Error de conexión SSL
- Qué significa
- Tu terminal muestra
curl: (35) SSL connect error. El handshake SSL/TLS falló — curl no pudo establecer una conexión segura con el servidor. - Causas
- Causas comunes: incompatibilidad de versión TLS (el servidor requiere TLS 1.3 pero tu curl solo soporta hasta TLS 1.2), incompatibilidad de suite de cifrado, mala configuración SSL del servidor (certificado expirado presentado durante el handshake, cadena incompleta), el servidor no soporta realmente HTTPS en el puerto dado, o un proxy o firewall está interceptando la conexión SSL (MITM).
- Cómo solucionarlo
- Fuerza una versión específica de TLS:
curl --tlsv1.2 URLocurl --tlsv1.3 URL. Comprueba lo que soporta el servidor:openssl s_client -connect api.example.com:443. Actualiza curl y OpenSSL a las últimas versiones. Si el servidor usa un certificado autofirmado, esto es normalmente el error 60 — el error 35 típicamente indica un fallo de handshake a nivel de protocolo.
$ curl https://legacy-server.example.com/apiError 56: Fallo de recepción — La conexión fue restablecida
- Qué significa
- Tu terminal muestra
curl: (56) Recv failure: Connection reset by peer. La conexión se estableció exitosamente, pero la recepción de datos falló — el servidor cerró o restableció la conexión inesperadamente durante la transferencia. - Causas
- Esto sucede a menudo cuando: el servidor se cae o reinicia durante la transferencia, un balanceador de carga o proxy corta la conexión (timeout de inactividad, solicitud demasiado grande), un firewall termina conexiones de larga duración, el servidor tiene un timeout de keep-alive más corto de lo esperado, o hay una interrupción de red entre cliente y servidor.
- Cómo solucionarlo
- Intenta la solicitud de nuevo — los problemas transitorios de red son la causa más común. Usa el modo detallado:
curl -v URLpara ver el punto exacto del fallo. Si el error ocurre durante cargas grandes, prueba la transferencia por fragmentos:curl -H "Transfer-Encoding: chunked" URL. Para operaciones Git que muestranRPC failed; curl 56, aumenta el buffer:git config http.postBuffer 524288000.
$ curl https://api.example.com/large-downloadError 60: Problema con el certificado SSL
- Qué significa
- Tu terminal muestra
curl: (60) SSL certificate problem: unable to get local issuer certificate. curl no pudo verificar el certificado SSL del servidor contra su paquete de CA (Autoridad de Certificación). El handshake TLS se completó a nivel de protocolo, pero la validación del certificado falló. - Causas
- Las causas más comunes: el servidor usa un certificado autofirmado, el certificado ha expirado, la cadena de certificados está incompleta (faltan certificados intermedios), el paquete de CA de curl está desactualizado (común en sistemas antiguos o en contenedores Docker), o el Common Name / SAN del certificado no coincide con el nombre de host solicitado.
- Cómo solucionarlo
- Actualiza el paquete de CA:
curl --cacert /path/to/cacert.pem URL. Descarga un paquete actualizado desde https://curl.se/ca/cacert.pem. Para diagnosticar:openssl s_client -connect api.example.com:443 -showcerts. Para certificados autofirmados en desarrollo, usacurl -k URL(nunca en producción — desactiva toda la verificación de certificados). En Docker, instala el paqueteca-certificates.
$ curl https://self-signed.example.com/apiOtros códigos de error
Éxito. La operación se completó sin ningún error.
Protocolo no soportado. La URL usa un protocolo para el que curl no fue compilado.
URL mal formada. La sintaxis de la URL es inválida o no pudo ser analizada.
No se pudo resolver el proxy. El nombre de host del proxy especificado no pudo ser resuelto.
Archivo parcial. La transferencia fue interrumpida y solo se recibió parte del archivo.
Error de escritura. curl no pudo escribir los datos recibidos en disco (permiso denegado o disco lleno).
No se pudo leer el archivo. Un archivo local referenciado en la solicitud no pudo ser abierto o leído.
Respuesta vacía del servidor. El servidor cerró la conexión sin enviar ningún dato.
Problema con el certificado CA SSL. No se pudo leer o analizar el archivo de certificado CA especificado.
Error de flujo HTTP/2. Ocurrió un error de protocolo HTTP/2 a nivel de flujo durante la transferencia.
Cómo depurar errores de curl
Cuando curl falla, estos tres flags te ayudan a identificar rápidamente la causa raíz — desde la resolución DNS hasta el handshake SSL y la carga útil de la respuesta.
- 1
Activar salida detallada
Ejecuta
curl -v URLpara ver el ciclo completo de solicitud/respuesta: resolución DNS, conexión TCP, handshake TLS, encabezados de solicitud enviados y encabezados de respuesta recibidos. Este es el flag de depuración más útil. - 2
Verificar el código de estado HTTP
Ejecuta
curl -o /dev/null -s -w "%{http_code}" URLpara obtener solo el código de estado HTTP (200, 404, 500, etc.) sin el cuerpo de la respuesta. Útil para verificaciones rápidas de estado y scripts. - 3
Mostrar errores silenciosamente
Ejecuta
curl -sS URLpara suprimir la barra de progreso (-s) pero seguir mostrando errores (-S). Perfecto para scripts donde quieres una salida limpia pero necesitas capturar fallos.
Preguntas frecuentes
¿Cómo verificar el código de salida de curl?
Después de ejecutar un comando curl, el código de salida se almacena en la variable especial del shell. En Bash/Zsh, ejecuta echo $? inmediatamente después del comando curl. En PowerShell, usa $LASTEXITCODE. En scripts, puedes verificarlo con un condicional: if curl -sf URL; then echo "OK"; else echo "Failed with code $?"; fi. El código de salida 0 significa éxito; cualquier otro número indica un error. Para ver tanto el código de estado HTTP como el código de salida de curl, combina curl -w "%{http_code}" -o /dev/null -s URL; echo "Exit: $?". Ten en cuenta que el código de salida de curl es diferente del código de estado HTTP — curl devuelve 0 incluso para HTTP 404 a menos que uses el flag --fail.
¿Cómo solucionar el error 28 de curl (tiempo de operación agotado)?
El error 28 significa que la solicitud excedió el tiempo máximo permitido. Primero, aumenta el tiempo de espera: curl --connect-timeout 30 --max-time 120 URL. El --connect-timeout limita la fase de conexión TCP, mientras que --max-time limita toda la operación. Luego, diagnostica el cuello de botella con curl -v URL — la salida detallada muestra exactamente dónde curl se queda atascado (DNS, conexión, TLS o transferencia). Soluciones comunes: verifica tu conexión de red y configuración DNS, comprueba que el servidor esté respondiendo (ping y telnet), omite proxies con --noproxy '*', y para descargas grandes agrega --retry 3 --retry-delay 5 para reintentos automáticos.
¿Cómo solucionar errores de certificado SSL de curl (error 60)?
El error 60 significa que curl no puede verificar el certificado SSL del servidor. La solución depende de la causa. Para un paquete de CA desactualizado: descarga uno nuevo desde https://curl.se/ca/cacert.pem y usa curl --cacert /path/to/cacert.pem URL. Para contenedores Docker: instala el paquete ca-certificates (apt-get install ca-certificates). Para certificados autofirmados en desarrollo: usa curl -k URL para omitir la verificación — pero nunca uses -k en producción ya que desactiva toda la verificación de certificados. Para diagnosticar: ejecuta openssl s_client -connect host:443 -showcerts para inspeccionar la cadena de certificados. Si el certificado ha expirado o el nombre de host no coincide, el problema está en el lado del servidor.
¿Qué significa el error 7 de curl (fallo al conectar)?
El error 7 significa que curl resolvió el nombre de host a una dirección IP pero no pudo establecer una conexión TCP. El servidor rechazó activamente la conexión o el intento de conexión se agotó a nivel de red. Causas comunes: el servicio no se está ejecutando en el host destino (verifica con systemctl status o docker ps), un firewall está bloqueando el puerto (prueba con telnet host port), estás usando el puerto incorrecto (por ejemplo, 80 en lugar de 443, o 8080 para un servidor de desarrollo), o la cola de conexiones del servidor está llena bajo alta carga. Para depurar: usa curl -v URL y busca "Connected to" o "Connection refused" en la salida.