HOWTO · Java
Cómo solucionar javax.net.ssl.SSLHandshakeException: el host remoto cerró la conexión durante el protocolo de enlace
Diagnostica por qué un protocolo de enlace SSL/TLS de Java fue cerrado por el host remoto y luego elige y verifica una solución en función de la evidencia del protocolo, el certificado, el cliente, la red o el servidor.
En esta página
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake significa que el protocolo de enlace SSL/TLS de Java no llegó a completarse porque el otro extremo cerró la conexión. El mensaje indica en qué punto se manifestó el fallo, pero por sí solo no explica por qué ocurrió. Entre las causas posibles están la incompatibilidad de protocolos o cifrados, los problemas con el certificado o la confianza, la configuración del cliente, los intermediarios de red y las políticas del servidor.
Qué significa la excepción
Durante un protocolo de enlace SSL/TLS, el cliente y el servidor negocian los protocolos y cifrados que usarán, y validan la identidad del servidor antes de intercambiar datos de la aplicación. Si el otro extremo cierra la conexión durante esa negociación, Java informa una SSLHandshakeException. Ese extremo podría ser el servidor previsto, un proxy, un balanceador de carga u otro dispositivo de red; por tanto, el mensaje no demuestra que haya sido el propio servidor de la aplicación quien cerró la conexión.
Interpreta la excepción como indicio de que el protocolo de enlace falló, no como prueba de que un certificado haya caducado o de que Java esté obsoleto. Primero identifica el endpoint exacto, el entorno de ejecución de Java y la biblioteca cliente implicados. La versión de Java de la línea de comandos puede diferir de la que utiliza un IDE, un servidor de aplicaciones, un contenedor o un servicio.
Diagnostica por qué el host remoto cerró la conexión
Avanza desde las observaciones hacia las posibles causas:
- Anota el nombre de host, el puerto, la hora del fallo, el entorno de ejecución de Java que realmente usa el proceso y la biblioteca HTTP u otra biblioteca cliente. Confirma que el endpoint y el puerto sean correctos y que se pueda acceder al servicio por la misma ruta que usa la aplicación.
- Compara los protocolos TLS y los cifrados que admiten el cliente y el servidor. Revisa la configuración del servidor o del balanceador de carga y los ajustes efectivos de la biblioteca cliente. Una incompatibilidad es plausible solo si ambos extremos carecen de opciones compatibles en común.
- Inspecciona el certificado del servidor presentado para ese nombre de host. Comprueba las fechas de validez, la coincidencia con el nombre de host y la cadena de certificados. Después, determina si el almacén de confianza configurado para el proceso Java confía en la cadena emisora. Inspeccionar un certificado y modificar un almacén de confianza son acciones distintas.
- Comprueba si un proxy, un cortafuegos, un dispositivo de inspección TLS u otro control de red termina o filtra la conexión. Compara los registros y el comportamiento de la ruta del cliente con los registros del servidor correspondientes a la misma hora.
La depuración TLS de Java puede revelar detalles de la negociación, pero el método para activarla y la salida dependen del cliente Java y de cómo se inicie. Usa el ajuste de diagnóstico documentado para el cliente o el entorno de ejecución. Mantén los registros en privado, ya que podrían revelar detalles de la conexión, y compara la negociación registrada con la configuración del servidor. No deduzcas la causa raíz únicamente a partir del texto de la excepción.
Aplica una solución específica
Cambia un ajuste cada vez y solo si el diagnóstico respalda ese cambio. Si el proceso usa un entorno de ejecución con una incompatibilidad conocida o sin actualizaciones de seguridad, actualízalo mediante el proceso de despliegue admitido por la aplicación y confirma qué entorno carga el proceso. Actualizar Java no es una solución general cuando el cierre se produce en el servidor.
Si el diagnóstico apunta a la negociación de protocolos, configúralos mediante el cliente HTTP, el socket o el framework concreto que use la aplicación. La propiedad de sistema https.protocols no es un ajuste universal para todos los clientes TLS de Java. Esta ilustración de la API crea un objeto SSLParameters, le asigna TLSv1.2 como lista de protocolos y, después, lee el valor almacenado. Solo muestra la llamada a la API de Java: un cliente real debe aplicar los parámetros apropiados a su propio socket o configuración, y el otro extremo debe admitir una opción compatible. Ejecuta este ejemplo:
import javax.net.ssl.SSLParameters;
public class TlsProtocolExample {
public static void main(String[] args) {
SSLParameters parameters = new SSLParameters();
parameters.setProtocols(new String[] {"TLSv1.2"});
System.out.println("Configured protocol: " + parameters.getProtocols()[0]);
}
}
En la ejecución registrada del ejemplo, la salida fue Configured protocol: TLSv1.2. La etiqueta «Configured protocol» permanece en inglés porque forma parte del bloque de salida inmutable.
Si al inspeccionar el certificado encuentras un problema con el nombre de host, la validez o la cadena, corrige el certificado que presenta el endpoint o su configuración de servidor. Si la cadena es correcta, pero el proceso Java no dispone de un ancla de confianza adecuada, revisa el almacén de confianza que selecciona ese proceso y sigue el procedimiento de gestión de confianza de la organización. No importes un certificado solo porque haya fallado el protocolo de enlace: añadir un certificado sin verificar puede debilitar las comprobaciones de identidad. keytool permite inspeccionar o modificar almacenes de claves de Java, pero el archivo, las opciones y los permisos necesarios dependen del entorno de ejecución y del despliegue. Consulta la documentación de ese entorno en lugar de copiar un comando con rutas supuestas.
Si las pruebas señalan a un proxy, un cortafuegos o una política remota, modifica únicamente la ruta o configuración implicada, en coordinación con su responsable. Si el cliente no puede determinar por qué se cerró la conexión, pide al administrador del servidor que compare los registros TLS del servidor, los protocolos y cifrados admitidos, la configuración de los certificados y los cambios recientes.
Verifica la solución y escala los problemas del servidor
Reintenta la misma solicitud con el mismo entorno de ejecución de la aplicación, el mismo endpoint y la misma ruta de red. Un protocolo de enlace correcto y la respuesta esperada de la aplicación demuestran que la conexión ya se completa; cambiar un ajuste por sí solo no lo demuestra. Si la excepción persiste, registra la hora, el endpoint, las versiones del entorno de ejecución y del cliente, los diagnósticos pertinentes del cliente y los registros correspondientes del servidor o del proxy. Compáralos para localizar qué extremo cierra la conexión. Oculta las credenciales y otros datos sensibles antes de compartir los registros. Si no puedes acceder a las pruebas del servidor, entrega estos detalles al administrador del servidor o de la red, en vez de suponer que otro cambio en el cliente resolverá el problema.