All Tools / Blog / How to Check SSL Certificate Expiry

How to Check SSL Certificate Expiry

3 min read

An expired SSL certificate takes a site offline immediately. Browsers show a full-page security warning, and most users won't click through. The fix takes minutes once you know the expiry date. The problem is that most teams don't check until after it's expired.

Check from the command line

OpenSSL connects to a host and prints the certificate dates:

echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

Output:

notBefore=Jan  1 00:00:00 2025 GMT
notAfter=Jan  1 00:00:00 2026 GMT

notAfter is the expiry date. To calculate days remaining:

EXPIRY=$(echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null \
    | openssl x509 -noout -enddate | cut -d= -f2)
echo "Expires: $EXPIRY"
echo "Days remaining: $(( ( $(date -d "$EXPIRY" +%s) - $(date +%s) ) / 86400 ))"

On macOS, replace date -d "$EXPIRY" with date -j -f "%b %d %T %Y %Z" "$EXPIRY".

Check with curl

curl -vI https://example.com 2>&1 | grep "expire date"

Faster than the OpenSSL pipeline when you just need the date.

Check a certificate file directly

If you have the .crt or .pem file on disk:

openssl x509 -noout -dates -in certificate.crt

Check in the browser

Click the padlock next to the URL:

  • Chrome: Connection is secure → Certificate is valid → expand the validity period
  • Firefox: Connection secure → More information → Security tab → View Certificate
  • Safari: Padlock → Show Certificate

The browser view also shows the issuing CA, which domains the certificate covers (Subject Alternative Names), and the full chain.

Check online

Paste a domain into the SSL checker and get the expiry date, issuing authority, and chain validity — without any command-line tools.

Automated expiry monitoring

Manual checks don't scale. For production, a weekly cron catches expiries before they cause downtime.

Shell script (sends email 30 days before expiry):

#!/bin/bash
DOMAIN="example.com"
EXPIRY=$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:443 2>/dev/null \
    | openssl x509 -noout -enddate | cut -d= -f2)
DAYS=$(( ( $(date -d "$EXPIRY" +%s) - $(date +%s) ) / 86400 ))

if [ $DAYS -lt 30 ]; then
    echo "SSL cert for $DOMAIN expires in $DAYS days ($EXPIRY)" \
        | mail -s "SSL expiry warning: $DOMAIN" you@example.com
fi

Add to cron:

0 9 * * 1 /path/to/check-ssl.sh

Free monitoring services:

  • UptimeRobot — monitors SSL expiry, alerts by email or Slack. Free tier covers 50 monitors.
  • StatusCake — free SSL checks with 7/14/30-day threshold alerts.
  • Cloudflare — auto-renews managed certificates and shows dashboard alerts.

Let's Encrypt certificates

Let's Encrypt certificates expire after 90 days by design. certbot should renew automatically. Verify the renewal is running:

systemctl status certbot.timer    # systemd
crontab -l | grep certbot         # cron

Test a dry run:

certbot renew --dry-run

If the dry run fails, fix it now — don't wait for the 30-day warning.

Certificate chain errors

A valid certificate can still cause chain errors if the intermediate CA is missing from the server configuration.

Layer What it is
Root CA Trusted by browsers (DigiCert, Let's Encrypt, etc.)
Intermediate CA Issued by root; signs your certificate
Your certificate Issued by intermediate; covers your domain

If the intermediate cert is missing, browsers show chain errors even though your cert itself hasn't expired. Check the full chain:

openssl s_client -connect example.com:443 -showcerts 2>/dev/null | grep "subject\|issuer"

Each certificate in the output should show a different subject/issuer pair, with the last one being the root CA.

Key takeaways

  • openssl s_client piped to x509 -noout -dates gives the expiry with one command.
  • curl -vI is faster when you just need the date.
  • Let's Encrypt certs expire in 90 days — verify certbot auto-renewal works with --dry-run.
  • Set up a weekly cron or UptimeRobot for automated 30-day alerts.
  • Chain errors mean the intermediate CA is missing from the server config, not that your cert expired.