CalcSnippets Search
Security 3 min read

`openssl s_client` Is the Command You Reach For When HTTPS Is Broken and Everyone Is Guessing

A practical OpenSSL s_client guide for developers who need to inspect TLS handshakes, certificates, and server responses without waiting for browser error screens to explain nothing.

Why TLS bugs waste so much time: the browser says the connection failed, the app says “SSL error,” and everybody starts theorizing before anyone inspects the handshake directly.

Why this command matters

When HTTPS or TLS is failing, you usually need to answer one of a few basic questions:

  1. did the server present a certificate
  2. is the certificate chain what I expected
  3. is SNI involved
  4. is the handshake completing at all

openssl s_client exists exactly for this kind of inspection. The OpenSSL documentation describes it as an SSL/TLS client program, which sounds broad, but for developers it is often the fastest way to interrogate a TLS endpoint from the terminal.

The starting command

For a standard HTTPS endpoint:

openssl s_client -connect example.com:443 -servername example.com

The -servername part is critical more often than people realize. Many hosts use SNI to decide which certificate to present. If you omit it, you can get misleading results and then debug the wrong problem.

What you are looking for

You are not trying to memorize every line of output. You are trying to answer a few concrete questions:

  1. did the handshake succeed
  2. what certificate chain was sent
  3. does the hostname match what you intended
  4. are there obvious verification issues

This is the right mindset. TLS debugging gets easier when you treat the command as an inspection tool, not as a wall of sacred text.

A few high-value flags

Show certificates:

openssl s_client -connect example.com:443 -servername example.com -showcerts

Briefer output:

openssl s_client -connect example.com:443 -servername example.com -brief

Test protocol-specific behavior if needed:

openssl s_client -connect example.com:443 -servername example.com -tls1_2

These variations help narrow whether the problem is the chain, the hostname routing, or a protocol mismatch.

A practical debugging pattern

Suppose production works in one environment but fails in another. Use s_client to compare both targets. If one presents the wrong certificate or fails only without SNI, you now have a real lead instead of a vague “SSL seems flaky” story.

This matters because TLS incidents often look like app bugs from far away. Sometimes the app is innocent and the edge configuration is the real culprit.

What this command is not

It is not a complete certificate management system, and it is not a beautiful UX. It is a direct inspection surface. That is why it stays useful. In the middle of an outage or deployment bug, direct inspection beats pretty dashboards.

Common mistakes

People often:

  1. forget -servername
  2. assume browser behavior tells the full story
  3. inspect only one environment
  4. stop after “it connected” without checking which certificate was actually served

That last one matters. A successful handshake with the wrong certificate is still a bug.

Why this command helps during incidents

In an outage, teams often lose time bouncing between infrastructure, app, and browser assumptions. s_client helps because it gives you one stable view from the terminal that is independent of browser caching and UI simplifications. It is not the entire answer, but it is often the first honest piece of evidence.

Final recommendation

When HTTPS is failing and the error messages are vague, reach for openssl s_client early. Use -connect, include -servername, inspect the presented certificates, and compare environments directly. TLS debugging becomes much more concrete once you stop treating the handshake as a black box.

Sources

Keep reading

Related guides