How to check when an SSL certificate expires

The short answer

Every SSL/TLS certificate has a "Not After" date (also called "Valid to" or "Expires on"). When that date passes, browsers show a full-page warning and the site gets marked "Not Secure". You can read the date in your browser, with openssl on the command line, or with a short script when you have many domains to check.

This matters more each year. Under the CA/Browser Forum's ballot SC-081, the longest a public certificate can be valid dropped from 398 days to 200 days on 15 March 2026. It drops to 100 days in March 2027 and to 47 days in March 2029 (summary of the timeline). That means more renewals, and more chances for one of them to fail.

Method 1: In the browser (one site, no tools)

1. Open the site using https://.

2. Click the site-information icon to the left of the address bar.

3. Choose the connection or security entry, then the option to view the certificate. The wording differs between browsers and versions.

4. Find Validity and read the Expires on / Not After date.

This is fine for one site. It gets slow past three or four, and it only shows the certificate *your* browser received.

Method 2: One openssl command

On macOS, Linux or WSL:

`bash

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

| openssl x509 -noout -enddate

`

The output looks like this:

`

notAfter=Dec 1 12:00:00 2026 GMT

`

Notes:

`bash

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

| openssl x509 -noout -checkend 2592000 && echo OK || echo "Expires within 30 days"

`

Method 3: Check a whole list of domains

Put one domain per line in domains.txt, then run:

`bash

while read -r d; do

end=$(echo | timeout 10 openssl s_client -connect "$d:443" -servername "$d" 2>/dev/null \

| openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)

if [ -z "$end" ]; then echo "$d, ERROR"; continue; fi

days=$(( ( $(date -d "$end" +%s) - $(date +%s) ) / 86400 ))

echo "$d, $(date -d "$end" +%F), $days days"

done < domains.txt | sort -t, -k3 -n

`

This prints domain, YYYY-MM-DD, N days, with the soonest expiry first. The date -d syntax is GNU (Linux/WSL). On macOS, install GNU coreutils and use gdate, or rewrite the date step with date -j -f.

Pitfall: don't remove the empty-result check. If a domain doesn't answer, $end is empty, and GNU date -d "" quietly returns today's date. Without the check, a dead site would look like it expires today, not like an error.

Common mistakes

Turning the dates into a routine

Checking once tells you today's status. To keep sites from lapsing, you need the list somewhere you'll look at, sorted by days left, with reminders before each date. Let's Encrypt stopped sending expiry reminder emails on 4 June 2025, so for many sites that reminder now has to come from you.

We make Lapsewatch, one option for that step. Paste lines like example.com, 2026-12-01 (the script above gives you this format) into its free checker. You get a table sorted by days left, with each row marked Expired, Urgent (7 days or less), Soon (30 days or less) or OK. It doesn't connect to your sites. It works from the dates you give it. Saved lists are free for up to 5 domains. The paid plans add a calendar file with reminders 30, 14 and 7 days before each expiry.

Try it