Mensaje de error
The remote certificate is invalid because of errors in the certificate chain: PartialChain
Suele combinarse con otros indicadores, por ejemplo, «PartialChain, RevocationStatusUnknown». HttpClient lo envuelve en «The SSL connection could not be established, see inner exception.»
.NET SslStream / HttpClient — X509ChainStatusFlags.PartialChain: the chain could not be built up to a root
Qué significa
.NET no pudo construir la cadena desde el certificado del servidor hasta ninguna raíz: falta un intermedio. Aunque la raíz sea de confianza (como en la reproducción), el hueco entre el certificado hoja y la raíz impide la validación. .NET puede descargar un intermedio que falta desde la URL de la extensión Authority Information Access del certificado, si existe y es accesible, así que el error aparece sobre todo con CA privadas, redes restringidas y contenedores.
Por qué ocurre
El servidor solo envía su certificado hoja
frecuenteKestrel, enlaces de IIS o proxies inversos configurados con un archivo de certificado o un PFX que solo contiene el certificado hoja.
No se puede obtener el intermedio
ocasionalLas CA privadas a menudo no tienen URL AIA, y los hosts o contenedores tras un firewall no llegan a las públicas, así que .NET no puede completar el hueco por sí mismo.
El intermedio solo existe en otros equipos
ocasionalEn Windows, los intermedios almacenados en caché o instalados en el almacén CertificateAuthority hacen que la cadena funcione en algunos equipos y falle en servidores recién instalados o en contenedores Linux.
Cómo solucionarlo
- 1.
Comprobar qué envía el servidor
Un solo certificado en el handshake, emitido por un intermedio, confirma el problema.
bash openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \ | grep -E '^ *[0-9]+ s:|^ *i:' - 2.
Enviar la cadena completa desde el servidor
En nuestra prueba, Kestrel (.NET 10) enviaba solo el certificado hoja cuando recibía un PEM con la cadena completa únicamente a través de ServerCertificate, y enviaba el intermedio en cuanto se establecía ServerCertificateChain como se muestra. En IIS, instala el intermedio en el almacén Entidades de certificación intermedias (Intermediate Certification Authorities) del servidor para que Windows lo envíe.
csharp // Kestrel sends intermediates only when they are given as ServerCertificateChain builder.WebHost.ConfigureKestrel(k => k.ConfigureHttpsDefaults(o => { o.ServerCertificate = X509Certificate2.CreateFromPemFile("fullchain.pem", "server.key"); var chain = new X509Certificate2Collection(); chain.ImportFromPemFile("fullchain.pem"); // leaf + intermediates o.ServerCertificateChain = chain; })); - 3.
Encontrar el intermedio que falta
La extensión AIA del certificado hoja apunta al certificado del emisor; añádelo a la configuración del servidor.
bash # The leaf names where its issuer can be downloaded (Authority Information Access) openssl x509 -in server.pem -noout -ext authorityInfoAccess