Mensaje de error
The remote certificate is invalid because of errors in the certificate chain: NotTimeValid
HttpClient lo notifica como excepción interna de «The SSL connection could not be established, see inner exception.». Pueden aparecer varios indicadores juntos, por ejemplo, «NotTimeValid, UntrustedRoot».
.NET SslStream / HttpClient — X509ChainStatusFlags.NotTimeValid
Qué significa
Un certificado de la cadena que construyó .NET está fuera de su período de validez según el reloj de este equipo: ha caducado o aún no es válido. NotTimeValid no dice qué certificado es; los elementos de la cadena en una devolución de llamada de validación, sí. La raíz y el nombre eran correctos; de lo contrario, aparecerían también otros indicadores.
Por qué ocurre
El certificado del servidor (o un intermedio) ha caducado
frecuenteLa renovación no se hizo, o el certificado renovado no se vinculó (enlace de IIS, configuración de Kestrel, referencia de Azure/Key Vault, balanceador de carga).
Un certificado recién emitido en un cliente con el reloj atrasado
ocasionalLos certificados válidos desde «ahora» fallan en equipos que van unos minutos atrasados.
El reloj del cliente está mal
ocasionalMáquinas virtuales restauradas desde instantáneas, dispositivos sin NTP o contenedores en un host cuyo reloj se desvía.
Cómo solucionarlo
- 1.
Comprobar las fechas del certificado servido
Compara notBefore y notAfter con la hora UTC actual.
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 el elemento de la cadena que falla
Una devolución de llamada de validación que registra ChainElementStatus y devuelve la decisión predeterminada muestra qué certificado está fuera de fecha sin debilitar la validación.
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 y volver a vincular
Renueva el certificado y actualiza todos los enlaces que lo sirven.
bash sudo certbot renew && sudo systemctl reload nginx # or renew in your CA / key vault and redeploy