Mensagem de erro
The remote certificate is invalid because of errors in the certificate chain: NotTimeValid
O HttpClient informa esse erro como a exceção interna de “The SSL connection could not be established, see inner exception.”. Várias flags podem aparecer juntas, por exemplo “NotTimeValid, UntrustedRoot”.
.NET SslStream / HttpClient — X509ChainStatusFlags.NotTimeValid
O que significa
Um certificado da cadeia que o .NET montou está fora do período de validade segundo o relógio desta máquina: expirou ou ainda não é válido. NotTimeValid não diz qual certificado; os elementos da cadeia em um callback de validação dizem. A raiz e o nome estavam corretos; caso contrário, outras flags apareceriam junto.
Por que acontece
O certificado do servidor (ou um intermediário) expirou
comumA renovação não aconteceu, ou o certificado renovado não foi associado (associação no IIS, configuração do Kestrel, referência do Azure/Key Vault, balanceador de carga).
Um certificado recém-emitido em um cliente com o relógio atrasado
ocasionalCertificados válidos a partir de “agora” falham em máquinas com o relógio alguns minutos atrasado.
O relógio do cliente está errado
ocasionalVMs restauradas de snapshots, dispositivos sem NTP ou contêineres em um host cujo relógio se desvia.
Como corrigir
- 1.
Verificar as datas do certificado servido
Compare notBefore e notAfter com a hora UTC atual.
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -subject -startdate -enddate - 2.
Registrar no log o elemento da cadeia que falha
Um callback de validação que registra ChainElementStatus no log e retorna a decisão padrão mostra qual certificado está fora da validade, sem enfraquecer a validação.
csharp // Log which certificate failed and why, without accepting it var handler = new HttpClientHandler { ServerCertificateCustomValidationCallback = (msg, cert, chain, errors) => { foreach (var element in chain!.ChainElements) foreach (var status in element.ChainElementStatus) Console.WriteLine($"{element.Certificate.Subject}: {status.Status} {element.Certificate.NotAfter:u}"); return errors == System.Net.Security.SslPolicyErrors.None; }, }; - 3.
Renovar e associar de novo
Renove o certificado e atualize cada associação que o serve.
bash sudo certbot renew && sudo systemctl reload nginx # or renew in your CA / key vault and redeploy