Skip to content
RU
← All articles

openssl s_client: 30 tested commands for TLS debugging

In short:

Start with openssl s_client -connect enterno.io:443 -servername enterno.io -verify_hostname enterno.io -verify_return_error -brief -no-interactive. SNI selects the server certificate; hostname verification and strict error handling tell you whether that certificate is acceptable for the name you meant to reach.

TLS handshake between a client and server with certificate verification
The TLS handshake needs both certificate trust and hostname verification.

This is a tested set of 30 commands, with observed output and process status from 13 November 2026. Use the route below to narrow down a failed handshake. Certificate and server settings are live, so re-run the relevant probe before acting on an old result.

What you need

You need OpenSSL, access to the target TCP port, and the DNS name the client expects. These probes ran with OpenSSL 3.5.8. If an older build rejects -no-interactive, omit that option and close standard input with </dev/null.

Step 1. Establish certificate trust and hostname identity

A successful TCP and TLS exchange is not a hostname check. OpenSSL documents that s_client normally continues after verification errors so you can inspect them. Add -verify_return_error to fail on a verification error, and -verify_hostname to check the intended DNS name. -servername only supplies SNI to select the virtual host.

$ openssl s_client -connect enterno.io:443 -servername enterno.io -verify_hostname wrong.example -verify_return_error -no-interactive
Verification error: hostname mismatch
Verify return code: 62 (hostname mismatch)
# exit 1
№PurposeCommandObserved outputexit
1Inspect the full handshakeopenssl s_client -connect enterno.io:443 -servername enterno.io -no-interactiveVerify return code: 0 (ok)0
2Get a compact handshake summaryopenssl s_client -connect enterno.io:443 -servername enterno.io -brief -no-interactiveProtocol version: TLSv1.30
3See the chain sent by the serveropenssl s_client -connect enterno.io:443 -servername enterno.io -showcerts -no-interactiveCertificate chain0
4Stop on a chain erroropenssl s_client -connect enterno.io:443 -servername enterno.io -verify_return_error -no-interactiveVerify return code: 0 (ok)0
5Check the intended hostnameopenssl s_client -connect enterno.io:443 -servername enterno.io -verify_hostname enterno.io -verify_return_error -no-interactiveVerify return code: 0 (ok)0
6Detect a hostname mismatchopenssl s_client -connect enterno.io:443 -servername enterno.io -verify_hostname wrong.example -verify_return_error -no-interactiveVerification error: hostname mismatch1
7Compact strict checkopenssl s_client -connect enterno.io:443 -servername enterno.io -brief -verify_return_error -no-interactiveProtocol version: TLSv1.30
8Request stapled OCSPopenssl s_client -connect enterno.io:443 -servername enterno.io -status -no-interactiveOCSP response: no response sent0

-showcerts lists certificates the server sent; it does not by itself prove that your trust store accepts the path. In this run -status printed OCSP response: no response sent. That tells us no stapled response arrived in this handshake, not whether the certificate was revoked. If you need dates, extract the leaf certificate from the chain and inspect it with openssl x509 -noout -dates.

For the next layer of diagnosis, see the certificate check guide, certificate types, and TLS handshake walkthrough.

Step 2. Isolate protocol and application negotiation

Force TLS 1.2 and TLS 1.3 separately when investigating client compatibility. Both worked in this sample. The TLS 1.1 probe stopped locally with no protocols available, so it says nothing conclusive about what the server accepts. Its trailing Verify return code: 0 (ok) is not evidence of a successful handshake.

$ openssl s_client -connect enterno.io:443 -servername enterno.io -tls1_1 -no-interactive
error:0A0000BF:SSL routines:tls_setup_handshake:no protocols available
# exit 1
№PurposeCommandObserved outputexit
9Force TLS 1.2openssl s_client -connect enterno.io:443 -servername enterno.io -tls1_2 -no-interactiveProtocol : TLSv1.20
10Force TLS 1.3openssl s_client -connect enterno.io:443 -servername enterno.io -tls1_3 -no-interactiveProtocol : TLSv1.30
11Probe legacy TLS 1.1openssl s_client -connect enterno.io:443 -servername enterno.io -tls1_1 -no-interactive40A7D934457F0000:error:0A0000BF:SSL routines:tls_setup_handshake:no protocols available:ssl/statem/s1
12Exclude TLS 1.3openssl s_client -connect enterno.io:443 -servername enterno.io -no_tls1_3 -no-interactiveProtocol : TLSv1.20
13Offer h2 and HTTP/1.1openssl s_client -connect enterno.io:443 -servername enterno.io -alpn h2,http/1.1 -no-interactiveALPN protocol: h20
14Offer HTTP/1.1openssl s_client -connect enterno.io:443 -servername enterno.io -alpn http/1.1 -no-interactiveALPN protocol: http/1.10
15Offer h2openssl s_client -connect enterno.io:443 -servername enterno.io -alpn h2 -no-interactiveALPN protocol: h20
16Restrict TLS 1.3 cipher suiteopenssl s_client -connect enterno.io:443 -servername enterno.io -tls1_3 -ciphersuites TLS_AES_128_GCM_SHA256 -no-interactiveNew, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA2560
17Offer X25519openssl s_client -connect enterno.io:443 -servername enterno.io -groups X25519 -no-interactiveexit 00
18Offer P-256openssl s_client -connect enterno.io:443 -servername enterno.io -groups P-256 -no-interactiveexit 00

Offering h2,http/1.1 selected h2; offering only http/1.1 selected that protocol. A default probe printed No ALPN negotiated because it did not offer ALPN. For cipher or key exchange diagnosis, -ciphersuites narrows TLS 1.3 suites and -groups narrows advertised groups. A passing probe covers this client/server pair, not every client implementation.

If browsers disagree, compare the ALPN result with the HTTP/2 and HTTP/3 guide. The SSL/TLS guide covers the protocol context.

SNI route selecting a virtual TLS host and its certificate
SNI selects a certificate; hostname verification is a separate step.

Step 3. Check SNI routing independently of trust

The same IP can serve multiple certificates. We reached 81.163.20.249:443 with SNI enterno.io and verified the site certificate. Without SNI the server delivered TRAEFIK DEFAULT CERT, a self-signed fallback. The non-strict probe still exited 0. That is why a script should not rely on the process status of the default invocation alone.

$ openssl s_client -connect enterno.io:443 -noservername -no-interactive
subject=CN=TRAEFIK DEFAULT CERT
Verify return code: 18 (self-signed certificate)
# exit 0
№PurposeCommandObserved outputexit
19Omit SNIopenssl s_client -connect enterno.io:443 -noservername -no-interactivesubject=CN=TRAEFIK DEFAULT CERT0
20Dial an IP but retain SNI and name checkopenssl s_client -connect 81.163.20.249:443 -servername enterno.io -verify_hostname enterno.io -verify_return_error -no-interactiveVerified peername: enterno.io0
21Dial an IP without SNIopenssl s_client -connect 81.163.20.249:443 -noservername -verify_hostname enterno.io -verify_return_error -no-interactiveVerification error: self-signed certificate1
22Force IPv4openssl s_client -connect enterno.io:443 -servername enterno.io -4 -no-interactiveConnecting to 81.163.20.2490
23Trace TLS state transitionsopenssl s_client -connect enterno.io:443 -servername enterno.io -state -no-interactiveSSL_connect:SSLv3/TLS read server session ticket0
24Dump received TLS extensionsopenssl s_client -connect enterno.io:443 -servername enterno.io -tlsextdebug -no-interactiveTLS server extension "server name" (id=0), len=00
25Print a summary on exitopenssl s_client -connect enterno.io:443 -servername enterno.io -prexit -no-interactiveVerify return code: 0 (ok)0
26Exercise reconnectsopenssl s_client -connect enterno.io:443 -servername enterno.io -reconnect -no-interactiveexit 00

When dialing an IP, keep -servername for routing and -verify_hostname for identity. Use -state or -tlsextdebug when the failure occurs before the normal summary. -reconnect exercises repeated connections; it is not a substitute for certificate verification.

Step 4. Confirm failure signatures and non-HTTPS TLS

With strict checking, the BadSSL examples stopped on an expired certificate, an untrusted self-signed certificate, and a hostname mismatch. The final probe tests SMTP STARTTLS on port 587: -starttls smtp performs the SMTP upgrade before beginning TLS. It does not model implicit TLS on port 465.

№PurposeCommandObserved outputexit
27Expired certificateopenssl s_client -connect expired.badssl.com:443 -servername expired.badssl.com -verify_return_error -no-interactiveVerification error: certificate has expired1
28Self-signed certificateopenssl s_client -connect self-signed.badssl.com:443 -servername self-signed.badssl.com -verify_return_error -no-interactiveVerification error: self-signed certificate1
29Wrong certificate nameopenssl s_client -connect wrong.host.badssl.com:443 -servername wrong.host.badssl.com -verify_hostname wrong.host.badssl.com -verify_return_error -no-interactiveVerification error: hostname mismatch1
30Upgrade SMTP with STARTTLSopenssl s_client -starttls smtp -connect smtp.gmail.com:587 -servername smtp.gmail.com -verify_hostname smtp.gmail.com -verify_return_error -no-interactiveVerified peername: smtp.gmail.com0

Verification and next action

For the hostname you expect, look for exit 0, Verification: OK, the verified peer name when requested, a negotiated TLS version, and the selected ALPN protocol if your application needs one. For a quick HTTPS certificate and configuration view, run the enterno SSL check; keep the command output when you need to debug the actual handshake.

If it fails

Observed textMeaning in this probeNext check
hostname mismatchThe certificate does not match the expected nameCompare SNI and -verify_hostname
self-signed certificateThe chain is not trusted by this clientInspect SNI and the CA path
no protocols availableThis client did not start that protocolInspect OpenSSL policy and supported versions
No ALPN negotiatedNo application protocol was selected hereOffer -alpn h2,http/1.1
OCSP response: no response sentNo stapled response arrivedCheck revocation by a separate method

How we made this

On 13 November 2026, method.py ran 30 commands from a Linux host using OpenSSL 3.5.8. Exact arguments, stdout, stderr, and exit codes are retained in the research data. Targets were public enterno.io, badssl.com, and smtp.gmail.com endpoints. Table cells show diagnostic excerpts, not the entire output. This AI-assisted article uses those recorded measurements; technical conclusions were checked against the saved output and OpenSSL documentation.

FAQ

Why did s_client exit 0 with a bad certificate?

The diagnostic client can continue after a verification error by default. The no-SNI sample did exactly that. Add -verify_return_error for a strict check.

Does -servername validate a hostname?

No. It sends SNI. Use -verify_hostname for the name check.

How can I see the server chain?

Use -showcerts; it lists what the server sent, not every locally trusted root.

Does the TLS 1.1 failure prove a server block?

No. This OpenSSL build rejected the attempt locally before a meaningful server negotiation.

Sources

Check your website right now

Check your site's SSL →
More articles: SSL/TLS
SSL/TLS
NET::ERR_CERT_AUTHORITY_INVALID: Causes and Exact Fixes
13.07.2026 · 2 650 views
SSL/TLS
SSL Certificate Chain: How to Verify and Fix an Incomplete One
15.04.2026 · 2 131 views
SSL/TLS
SSL Handshake Failed: What Causes It and How to Fix It
15.04.2026 · 2 042 views
SSL/TLS
Russian Trusted Root CA and Sub CA on Servers: Install
15.06.2026 · 1 734 views