ERR_CERT_DATE_INVALID has two completely different causes and one of them has nothing to do with the website. The certificate is outside its validity window - either because it genuinely expired, or because your device thinks it is a different date than it is. Deciding which takes about five seconds.
Check your own clock first
Open any other HTTPS site - a search engine, a news site, anything. If they all fail the same way, the certificates are fine and your device's date is wrong. This happens after a dead CMOS battery, on a machine restored from an old image, and on phones that have lost network time.
timedatectl # Linux
sudo sntp -sS time.apple.com # macOS, force a sync
w32tm /resync # Windows, elevated promptSet the clock, enable automatic synchronisation, reload. If every site now works, you are done and no certificate was ever at fault.
If only one site fails, read the actual dates
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com </dev/null 2>/dev/null \
| openssl x509 -noout -dates -subjectYou get two lines, notBefore and notAfter. A notAfter in the past is a plain expiry. A notBefore in the future is rarer and means a certificate was installed ahead of its start date, which some CAs backdate by a few hours to allow for clock skew.
The renewal that ran and did not help
This is worth checking before you go looking for a failed renewal, because it looks identical from a browser. Web servers load the certificate at startup and keep it in memory. Certbot writes new files and, unless a deploy hook tells the server, nothing on the wire changes.
openssl x509 -in /etc/letsencrypt/live/yourdomain.com/fullchain.pem -noout -dates
systemctl reload nginxIf the file on disk is current and the served certificate is not, the reload is the entire fix. Make it automatic so it does not recur:
certbot renew --deploy-hook "systemctl reload nginx"When the renewal genuinely failed
Do not wait for the next scheduled attempt to find out why. Ask now:
certbot renew --dry-run
systemctl list-timers | grep certbotThe dry run reproduces the real failure without touching rate limits. Three causes account for most of them.
- The HTTP-01 challenge cannot reach the server. Let's Encrypt fetches a file under
/.well-known/acme-challenge/over plain HTTP. A blanket HTTP-to-HTTPS redirect is fine - the redirect is followed - but a WAF rule, a firewall, or adeny allon hidden directories is not. Test it by hand: put a file there and fetch it from outside. - DNS moved. If the domain now points somewhere else, the challenge is served by a different machine and validation fails on the one holding the certificate.
- The timer is off. A migration or a restore can leave
certbot.timerdisabled, and nothing complains until an expiry three months later.systemctl enable --now certbot.timerputs it back.
On cPanel and shared hosting
AutoSSL renews certificates on a schedule and reports failures in WHM under SSL/TLS → Manage AutoSSL → Logs. The usual reasons it stops are a domain that no longer resolves to the server, a subdomain added after the last successful run, and a redirect that breaks the validation request. The log names the failing domain explicitly, which saves guessing.
Catch the next one before it happens
The reason expiry is such a common outage is that the warning email and the renewal both depend on things that quietly stop working. Independent monitoring costs nothing:
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null \
| openssl x509 -noout -checkend $((14*86400)) \
|| echo "certificate for yourdomain.com expires within 14 days"Run that from cron on a different machine than the one holding the certificate. Checking from the same server is how a failed renewal and a failed alert end up sharing a cause.