Mensagem de erro
The remote certificate is invalid because of errors in the certificate chain: PartialChain
Muitas vezes aparece combinado com outras flags, por exemplo “PartialChain, RevocationStatusUnknown”. O HttpClient o encapsula em “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
O que significa
O .NET não conseguiu montar a cadeia que vai do certificado do servidor até alguma raiz: falta um intermediário. Mesmo quando a raiz é confiável (como na reprodução), a lacuna entre o certificado folha e a raiz impede a validação. O .NET consegue baixar um intermediário ausente pela URL da extensão Authority Information Access do certificado, quando ela existe e está acessível, por isso o erro aparece principalmente com CAs privadas, redes restritas e contêineres.
Por que acontece
O servidor envia só o certificado folha
comumKestrel, associações do IIS ou proxies reversos configurados com um arquivo de certificado ou PFX que contém só o certificado folha.
Não é possível buscar o intermediário
ocasionalCAs privadas muitas vezes não têm URL de AIA, e hosts ou contêineres atrás de firewall não alcançam as URLs públicas, por isso o .NET não consegue preencher a lacuna sozinho.
O intermediário só existe em outras máquinas
ocasionalNo Windows, certificados intermediários em cache ou instalados no repositório CertificateAuthority fazem a cadeia funcionar em algumas máquinas e falhar em servidores novos ou em contêineres Linux.
Como corrigir
- 1.
Verificar o que o servidor envia
Um único certificado no handshake, emitido por um intermediário, confirma o 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.
Fazer o servidor enviar a cadeia completa
No nosso teste, o Kestrel (.NET 10) enviou só o certificado folha quando recebeu um PEM com a cadeia completa apenas por ServerCertificate, e passou a enviar o intermediário assim que ServerCertificateChain foi definido como mostrado. No IIS, instale o intermediário no repositório Autoridades de Certificação Intermediárias (Intermediate Certification Authorities) do servidor para que o Windows o envie.
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 o intermediário ausente
A extensão AIA do certificado folha aponta para o certificado do emissor; adicione-o à configuração do servidor.
bash # The leaf names where its issuer can be downloaded (Authority Information Access) openssl x509 -in server.pem -noout -ext authorityInfoAccess