Checking an SSL Certificate From the Command Line

Updated 2026-03-27 · By SPUNK13 · Back to spunk.bet

Certificate problems are almost always one of three things: it expired, the intermediate chain is missing, or the name does not match. All three are diagnosable in under a minute with openssl, and none of them require a website that grades your server.

The One Command to Memorise

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -dates -subject -issuer

The -servername flag sends SNI. Omit it on a host that serves many sites from one IP and you will be handed the default certificate, then spend twenty minutes debugging a mismatch that does not exist. The </dev/null closes stdin so the command returns instead of sitting in an interactive session.

Expiry, Including the Machine-Readable Check

# human readable
... | openssl x509 -noout -enddate
# notAfter=Sep 12 08:14:00 2026 GMT

# exit non-zero if it expires within 14 days - use this in cron
... | openssl x509 -noout -checkend 1209600

-checkend takes seconds and returns a shell exit status, which makes it the right primitive for monitoring. Since most public certificates now have lifetimes measured in weeks rather than years, and the industry is moving toward much shorter maximum lifetimes, unattended renewal plus an alert at 14 days is the minimum viable setup.

The Chain Problem

The most common "works in Chrome, fails in curl and on Android" bug is a server sending only the leaf certificate. Desktop browsers often cache intermediates from previous visits and paper over it; other clients do not. Check what the server actually sends:

openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null \
  | grep -E 's:|i:'

You want to see the leaf, then one or more intermediates, forming an unbroken issuer chain up to a root your clients trust. The root itself does not need to be sent. If only one certificate comes back, your server config is pointing at cert.pem where it should point at fullchain.pem.

Name Matching

... | openssl x509 -noout -ext subjectAltName

Common Name has been ignored by browsers for years; only Subject Alternative Names count. A wildcard such as *.example.com covers one label only — it matches api.example.com but not a.b.example.com and not the bare example.com, which must be listed separately.

Protocol and Cipher Checks

openssl s_client -connect example.com:443 -servername example.com -tls1_2 </dev/null
openssl s_client -connect example.com:443 -servername example.com -tls1_3 </dev/null
# should fail:
openssl s_client -connect example.com:443 -tls1_1 </dev/null

TLS 1.0 and 1.1 are deprecated and should be refused. TLS 1.2 and 1.3 should both succeed unless you have a specific reason to require 1.3 only. For a full audit, testssl.sh is a single shell script that checks protocols, ciphers, known vulnerabilities and HSTS in one run, offline and without sending your hostname to a third party.

Non-HTTPS Services

Mail servers and databases use STARTTLS, which needs a protocol hint:

openssl s_client -connect mail.example.com:587 -starttls smtp
openssl s_client -connect db.example.com:5432 -starttls postgres

What to Automate

Three checks on a schedule cover most incidents: -checkend for expiry on every public hostname including ones you forgot about, a chain-length assertion so a renewal that drops the intermediate is caught immediately, and a check that HSTS is still being sent. Certificate outages are unusual among incidents in that they are perfectly predictable in advance, which makes not catching them purely an operational failure.

Want More?

Explore our complete collection of free tools and resources.

Visit spunk.bet
400+ Free Tools Free Casino Meme Generator Birth Charts Scam Database BPM Calculator