Перейти к содержимому
ecdsa.com
.NET SslStream / HttpClient.NET

Сообщение об ошибке

The remote certificate is invalid because of errors in the certificate chain: PartialChain

Часто сочетается с другими флагами, например «PartialChain, RevocationStatusUnknown». HttpClient оборачивает её в «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

Что это означает

.NET не смог построить цепочку от сертификата сервера ни до одного корневого: не хватает промежуточного сертификата. Даже если корневому сертификату доверяют (как в воспроизведении), разрыв между конечным и корневым сертификатом не даёт пройти проверку. .NET умеет загружать недостающий промежуточный сертификат по URL из расширения Authority Information Access в сертификате, если такой URL есть и доступен, поэтому ошибка возникает в основном с частными CA, в закрытых сетях и в контейнерах.

Почему это происходит

Как исправить

  1. 1.

    Проверьте, что отправляет сервер

    Проблему подтверждает один-единственный сертификат в рукопожатии, выпущенный промежуточным CA.

    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.

    Отправляйте с сервера полную цепочку

    В нашей проверке Kestrel (.NET 10), получив PEM с полной цепочкой только через ServerCertificate, отправлял лишь конечный сертификат, а промежуточный начал отправлять, когда ServerCertificateChain задали, как показано в примере. Для IIS установите промежуточный сертификат в хранилище «Промежуточные центры сертификации» (Intermediate Certification Authorities) на сервере, чтобы Windows его отправляла.

    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.

    Найдите недостающий промежуточный сертификат

    Расширение AIA в конечном сертификате указывает на сертификат издателя; добавьте его в конфигурацию сервера.

    bash
    # The leaf names where its issuer can be downloaded (Authority Information Access)
    openssl x509 -in server.pem -noout -ext authorityInfoAccess

Связанные ошибки

Открыть всю базу ошибок подписей