Skip to content
Latchkey

openssl s_client: Usage, Options & Common CI Errors

openssl s_client opens a raw TLS connection to inspect the certificate and handshake.

openssl s_client is the tool for debugging TLS failures in CI - expired certs, missing SNI, broken chains. The recurring gotchas are needing -servername for SNI and that the command waits on stdin unless you redirect it.

What it does

openssl s_client establishes a TLS connection to a host:port and prints the negotiated protocol, cipher, certificate chain, and verification result. It is the standard way to diagnose "certificate verify failed" and SNI/chain problems that break HTTPS calls in a pipeline.

Common usage

Terminal
echo | openssl s_client -connect example.com:443 -servername example.com
openssl s_client -connect example.com:443 -showcerts </dev/null
# Check expiry:
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
openssl s_client -connect host:443 -tls1_2 </dev/null   # force TLS 1.2
echo | openssl s_client -connect host:443 -servername host 2>/dev/null | grep 'Verify return'

Options

FlagWhat it does
-connect <host>:<port>Endpoint to connect to
-servername <name>Send SNI (needed for virtual hosts)
-showcertsPrint the full certificate chain
-CAfile <file>Verify against a specific CA bundle
-tls1_2 / -tls1_3Force a TLS version
-quiet / </dev/nullAvoid waiting on stdin

Common errors in CI

s_client reads stdin and stays open, hanging the job - always feed echo | or </dev/null. "verify error:num=20:unable to get local issuer certificate" / num=21 means the chain is incomplete or the runner's CA bundle is missing the root (install ca-certificates / update-ca-certificates). "num=10: certificate has expired" is a literal expiry. Forgetting -servername makes the server return its default cert, causing a confusing hostname-mismatch - always send SNI. "Verify return code: 0 (ok)" is the pass signal to grep for.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →