Pular para o conteúdo
ecdsa.com
.NET SslStream / HttpClient.NET

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

Como corrigir

  1. 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. 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. 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

Erros relacionados

Ver toda a base de erros de assinatura