How to check SSL certificate expiry
Pipe the served certificate into openssl x509 -noout -enddate and read the notAfter line, which is the expiry instant in GMT. For a pass or fail answer inside a pipeline, use openssl x509 -noout -checkend 2592000, which prints a verdict and exits 1 when the certificate dies inside the next 30 days.
Checker offline. Follow the manual steps below, they give the same answer.
Why check this
A certificate that runs out takes every client down at the same second, and it fails before the first byte of HTTP, so the service returns nothing an API client can parse. Run this on staging sign-off, after any infrastructure change that moves a hostname to a new load balancer, and as a scheduled job against production. Renewal automation fails quietly, and the first visible symptom is the outage itself.
Prerequisites
- openssl 1.1.1 or later. See the s_client manual and the x509 manual.
- Outbound access to port 443 on the host under test.
- GNU
datefor step 2. Git Bash and Linux have it. On macOS usedate -j -f '%b %e %T %Y %Z'instead.
Steps
- Step 1.
Read the validity window off the live connection.
openssl s_client -connect www.cloudflare.com:443 -servername www.cloudflare.com </dev/null 2>/dev/null | openssl x509 -noout -datesnotBefore=Sep 3 07:35:04 2026 GMT notAfter=Dec 2 07:35:03 2026 GMT</dev/nullmatters. Without its_clientkeeps the connection open waiting for you to type, and the command never returns. - Step 2.
Convert
notAfterinto days remaining, for every hostname you care about.for host in www.cloudflare.com example.com expired.badssl.com; do end=$(openssl s_client -connect "$host:443" -servername "$host" </dev/null 2>/dev/null \ | openssl x509 -noout -enddate | cut -d= -f2) days=$(( ( $(date -d "$end" +%s) - $(date +%s) ) / 86400 )) printf '%-22s %5d days\n' "$host" "$days" donewww.cloudflare.com 81 days example.com 46 days expired.badssl.com -4169 days - Step 3.
Turn the number into an exit code so a pipeline can stop on it.
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -checkend 2592000; echo "exit=$?"Certificate will not expire exit=02592000 is 30 days in seconds. Raise it until the command fails, and the first failing value brackets the real headroom.
- Step 4.
Confirm the failing shape against a host that is known to be dead.
openssl s_client -connect expired.badssl.com:443 -servername expired.badssl.com </dev/null 2>/dev/null | openssl x509 -noout -dates -checkend 0notBefore=Apr 9 00:00:00 2015 GMT notAfter=Apr 12 23:59:59 2015 GMT Certificate will expire
How to read the result
| What you see | What it means | What to do |
| --- | --- | --- |
| notAfter more than 30 days out | Normal state for a 90-day certificate | Nothing. Record the date in the release ticket. |
| Certificate will expire from -checkend | Expiry falls inside the window you passed | Check the renewal job ran, not only that it is configured. |
| A negative day count | The certificate is already invalid | Treat as a production outage. Clients fail closed, no retry helps. |
| notBefore in the future | The certificate is not valid yet | A clock skew or an early deploy. Compare with date -u on the server. |
Common mistakes
Thresholds
What to check next
- How to check SSL certificate from command line: read the rest of the certificate once the dates are known good.
- How to check certificate chain: a renewal that drops the intermediate fails the same way to some clients.
- How to check certificate revocation: a certificate can be dead well before
notAfter. - How to test SSL configuration: the full TLS pass this check belongs to.
- Ssl certificate checker: the same read without a terminal.
FAQ
How to check SSL certificate expiration date?
Run step 1 and read notAfter. The value is UTC, printed in the openssl format Dec 2 07:35:03 2026 GMT. Your browser shows the same instant in local time, so the calendar day can differ by one without anything being wrong.
How to check certificate expiration date with openssl?
openssl s_client fetches it, openssl x509 -noout -enddate prints it. Keep them as two processes joined by a pipe. s_client alone prints the certificate plus a session dump, and x509 alone reads a file rather than a server.
How to determine SSL certificate expiration date from a PEM file?
Skip s_client and point x509 at the file: openssl x509 -in cert.pem -noout -enddate. The same flag works on a bundle, but it reads only the first certificate in the file, which is the leaf.
Does -checkend cover the intermediate certificates too?
No. It reads one certificate, the leaf. An intermediate that expires first breaks the same connection, so add a chain check rather than trusting a green leaf.
Verified
Verified by Maks Vernyopenssl 3.1.1
Each output block is what the command above it printed on that date, on the host named in the step. Figures read from a live site move between runs. Compare the shape of the answer rather than the digits, and see the methodology for how a page is re-verified.
Related on this site
- Checker: tls-certificate TLS versions offered, certificate chain, expiry, SANs
- API testing checklist
- TLS and certificate review
- Website launch checklist
- All security headers and tls checks
basic5 minpublished updated Maks Verny