Mensaje de error
Received an unexpected EOF or 0 bytes from the transport stream.
También se muestra como
- System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.
HttpClient lo envuelve en «The SSL connection could not be established, see inner exception.» En los registros de las aplicaciones de .NET Framework, la misma situación suele aparecer como «Authentication failed because the remote party has closed the transport stream.»
.NET SslStream / HttpClient — IOException: the peer closed the connection during the TLS handshake
Qué significa
El otro extremo (o un dispositivo intermedio) cerró la conexión TCP mientras SslStream estaba en pleno handshake TLS, sin enviar ninguna alerta TLS. .NET no tiene más motivo que comunicar que el flujo cerrado. Normalmente, el servidor rechazó el handshake en silencio o un proxy o firewall lo cortó.
Por qué ocurre
El servidor cierra los handshakes que no acepta
frecuenteNo hay ninguna versión del protocolo ni algoritmo de cifrado en común, falta el nombre SNI o es desconocido, o el servidor exige algo que el cliente no ofreció; y además el servidor cierra la conexión en lugar de enviar una alerta.
Un proxy o firewall corta la conexión
frecuenteLas redes que exigen un proxy, los firewalls que filtran TLS y los clientes VPN terminan en silencio las conexiones bloqueadas.
Aplicaciones de .NET Framework que solo ofrecen versiones antiguas de TLS
ocasionalLas aplicaciones destinadas a .NET Framework 4.5 o anterior sin la configuración de TLS predeterminada del sistema operativo pueden ofrecer solo TLS 1.0, que los servidores modernos descartan.
Cómo solucionarlo
- 1.
Probar el handshake desde el mismo equipo
Si openssl s_client también se corta, el problema está en la red o en el servidor; si funciona, compara las versiones del protocolo y el SNI con los del cliente .NET.
bash # Does a plain TLS handshake from the same host work? openssl s_client -connect api.example.com:443 -servername api.example.com -brief </dev/null openssl s_client -connect api.example.com:443 -servername api.example.com -tls1_2 -brief </dev/null - 2.
Usar el proxy obligatorio
Configura el proxy en el controlador (o mediante HTTPS_PROXY en Linux) cuando la red no permita conexiones directas.
csharp // Use the corporate proxy explicitly (HttpClient also honours HTTPS_PROXY / system settings) var handler = new SocketsHttpHandler { Proxy = new WebProxy("http://proxy.example.net:3128"), UseProxy = true }; using var client = new HttpClient(handler); - 3.
.NET Framework: habilitar TLS 1.2
Cambia el destino a 4.7 o posterior para que el sistema operativo elija el protocolo, o añade TLS 1.2 a ServicePointManager.SecurityProtocol hasta que puedas hacerlo.
csharp // .NET Framework 4.x apps compiled for old targets may still offer only TLS 1.0: // target 4.7+ (OS defaults) or, as a stop-gap, enable TLS 1.2 explicitly System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;