Skip to main content

How to Test SSL Properly: Certificate Chain, Intermediate Issues, and Tool‑Based Checks

This guide shows hands‑on SSL testing using browser certificate viewers + command‑line tools so you can identify problems like missing intermediates, broken chains, and the classic “works in Chrome but fails on iOS/Firefox/API clients” scenario.

Z
Written by Zoe Handscomb
Updated over 3 months ago

Scope

This article is for testing/diagnosis only.

It does help you:

  • Confirm you’re testing the right hostname

  • Validate the certificate name (SAN), expiration, and issuer

  • Verify the certificate chain (leaf + intermediates)

  • Check the TLS handshake (protocol/cipher/SNI) and read errors

It does not cover:

  • Enabling/installing SSL

  • Forcing HTTPS / redirect configuration

  • Fixing mixed content warnings

If your issue is “page shows secure but some images/scripts are blocked,” that’s usually mixed content (outside this article).


Fast triage checklist (2 minutes)

Run these in order — most SSL problems are found here:

  1. Hostname

    • Are you testing the exact hostname your visitors use? (example.com vs www.example.com vs app.example.com)

  2. Certificate name (SAN)

    • The cert must include the hostname in Subject Alternative Name (SAN)

  3. Expiration / validity dates

    • Ensure it’s not expired and not “not yet valid”

  4. Certificate chain (intermediates)

    • The server must send the leaf certificate + all required intermediate certificates (a “full chain”)

  5. TLS handshake

    • Confirm the connection negotiates a compatible TLS version and the correct cert is served via SNI

If you only do one command-line test, do the curl check below (it validates hostnames and chain like real clients do).


1) Browser checks (quick, but don’t stop at the padlock)

Browsers can mask problems because they may cache intermediate certificates or fetch them automatically. Still, they’re useful for quick inspection.

What to check in any browser

Open your site over HTTPS, then view certificate details and confirm:

  • Issued to / SAN includes your exact hostname

  • Expires on is in the future

  • Certificate path / chain shows a complete path up to a trusted root

  • No warnings about “missing issuer” or “unknown authority”

Chrome / Edge (typical path)

  • Click the padlock (or tune icon) → Connection is secureCertificate is valid

  • Look for:

    • Subject Alternative Name (SAN)

    • Valid from / to

    • Certification Path (the chain)

Firefox (good for catching chain issues)

  • Click the padlock → Connection secureMore InformationView Certificate

  • Pay attention to the Certificate Hierarchy and any “unknown issuer” warnings

Safari (macOS)

  • Click the padlock → Show Certificate

  • Expand details to view the chain and validity dates

If the browser looks fine but some devices/apps fail, jump to Command‑line checks and Chain troubleshooting (that’s where the real answers usually are).


2) Command-line checks (best for real diagnosis)

A) OpenSSL: inspect the certificate chain the server is actually sending

Use this when you suspect missing intermediates, wrong chain order, or SNI problems.

Copy/paste (recommended):

openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null

What this does:

  • -connect example.com:443 tests HTTPS on port 443

  • -servername example.com enables SNI (critical on shared IPs/load balancers)

  • -showcerts prints the server-sent chain (leaf + intermediates)

  • </dev/null prevents OpenSSL from waiting for input

How to read the output

Look for these sections/lines:

  1. Certificate chain
    You’ll see entries like 0, 1, 2

    • 0 is usually the leaf/server certificate

    • 1, 2, … are intermediate certificates

Red flag: you only see 0 (leaf) and nothing else → often a missing intermediate / incomplete chain.

  1. Subject and issuer
    You may see lines like:

  • subject=...

  • issuer=...

This helps confirm the cert presented is the one you expect.

  1. Verify return code
    Near the bottom, you’ll see something like:

  • Verify return code: 0 (ok) ✅ usually indicates the chain is trusted from the perspective of this machine’s trust store

  • Non‑zero codes can indicate chain problems (common ones: missing intermediate, untrusted issuer)

Note: OpenSSL behavior can vary by platform/build and which CA bundle it uses. If OpenSSL results are confusing, use the curl test next—curl’s errors tend to match what users/apps see.

Quick SAN + expiry check (no scrolling)

This pulls out the key fields from the cert OpenSSL receives:

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

You’re looking for:

  • notAfter= (expiration)

  • subjectAltName= includes DNS:example.com (and/or DNS:www.example.com, etc.)

Test “SNI mismatch” (common “wrong cert served” cause)

Run the same check without SNI:

openssl s_client -connect example.com:443 -showcerts </dev/null

If the certificate changes (or becomes “wrong”), you likely have an SNI configuration issue: some clients without SNI (or misrouted traffic) may receive the wrong certificate.

Test a specific IP (useful when DNS points to multiple servers)

If you suspect only one backend is misconfigured, test a specific IP while still requesting the hostname via SNI:

openssl s_client -connect 203.0.113.10:443 -servername example.com -showcerts </dev/null

B) curl: validate like a real client (hostname + chain)

This is the best all-around test because curl typically:

  • Checks the chain

  • Checks the hostname match

  • Produces clear error messages

Copy/paste:

curl -vI https://example.com

How to read the output

In a healthy connection, you’ll typically see lines indicating:

  • The TLS connection was established (TLS version/cipher)

  • The certificate matches the hostname

  • Certificate verification succeeded

If it fails, curl usually ends with a clear reason, such as:

  • SSL certificate problem: unable to get local issuer certificatemissing intermediate / incomplete chain

  • SSL certificate problem: certificate has expiredexpired

  • SSL: no alternative certificate subject name matches target host nameSAN/hostname mismatch

  • SSL certificate problem: self signed certificateuntrusted/self-signed chain

Inspect even when it fails (diagnostic mode)

If curl refuses to connect due to SSL, you can still see details by skipping verification:

curl -vkI https://example.com

This is for diagnosis only. The goal is to read what cert is being served.

Check IPv4 vs IPv6 (common “some networks fail” cause)

Sometimes IPv6 points somewhere different and serves a different cert/chain.

curl -vI -4 https://example.com curl -vI -6 https://example.com

If IPv4 works but IPv6 fails (or vice versa), you likely have different SSL setups on different addresses/endpoints.

Test a specific IP without changing DNS

This is extremely useful for diagnosing specific backends:

curl -vI --resolve example.com:443:203.0.113.10 https://example.com

3) Understanding certificate chains (why intermediates matter)

An SSL/TLS “certificate chain” is typically:

  1. Leaf (server) certificate – issued to your hostname (your site)

  2. Intermediate certificate(s) – issued by a Certificate Authority (CA) to sign leaf certs

  3. Root certificate – trusted by the device/browser OS trust store

Important rule:
Your server should send the leaf + intermediate(s).
The root is normally not sent (clients already have it if they trust that CA).

If the server does not provide the right intermediate(s), many clients cannot build a trusted path and will fail with “unknown issuer” or “unable to get local issuer certificate.”


4) Certificate chain & intermediate troubleshooting (the “works in Chrome but not X” section)

Problem: Missing intermediate certificate (incomplete chain)

Typical symptoms

  • Works in Chrome on your laptop, fails on:

    • iOS Safari

    • Some Android devices

    • API clients (curl, Python, Java, monitoring tools)

  • curl shows: unable to get local issuer certificate (or similar)

How to confirm

  • openssl s_client ... -showcerts shows only the leaf cert (or an incomplete chain)

  • Browser “certificate path” looks incomplete on some devices

Why Chrome might still work

  • Chrome may have cached the missing intermediate from another site

  • Some clients fetch intermediates automatically; others don’t (or can’t)


Problem: Wrong intermediate / wrong chain order

Typical symptoms

  • Some clients validate successfully, others fail

  • Errors vary by platform (especially across older OS versions)

How to confirm

  • OpenSSL shows multiple certs, but the issuer/subject linkage looks odd

  • The chain contains an intermediate that doesn’t match the leaf certificate issuer

Common real-world cause

  • A renewed certificate was installed, but the old intermediate bundle remained

  • The server sends the chain in an unusual order or includes unrelated intermediates


Problem: Cross-signed / alternate chain issues (older devices)

Typical symptoms

  • New devices are fine, older devices fail (or vice versa)

  • “Unknown authority” on older OS versions that haven’t updated trust stores

How to confirm

  • Compare results from multiple clients (curl/OpenSSL on different machines, or a failing device)

  • OpenSSL output shows a chain that the failing device does not accept

What’s happening

  • Some CAs have multiple valid paths (alternate intermediates). Certain older clients only trust one of them.


Problem: SNI mismatch (wrong certificate served)

Typical symptoms

  • Correct cert in browser, wrong cert in some tools or older clients

  • Name mismatch errors appear intermittently

How to confirm

  • Compare OpenSSL with and without -servername example.com

  • If cert changes, SNI routing is involved


Problem: Different certificate on different endpoints (load balancer / multiple IPs / IPv6)

Typical symptoms

  • Works from one network but fails from another

  • IPv4 works, IPv6 fails (or the reverse)

How to confirm

  • curl -4 vs curl -6

  • curl --resolve to test specific backends

  • OpenSSL test a specific IP while keeping -servername


5) Common symptoms → likely cause (quick mapping)

  • Browser error: “Your connection is not private” / NET::ERR_CERT_COMMON_NAME_INVALID
    Likely causes:

    • Hostname mismatch (SAN doesn’t include the domain you’re visiting)

    • You’re testing www but cert is only for apex (or the reverse)
      What to check:

    • SAN list in browser certificate details

    • curl -vI https://hostname (look for hostname match)

  • Firefox: SEC_ERROR_UNKNOWN_ISSUER or similar “unknown authority”
    Likely causes:

    • Missing intermediate / incomplete chain

    • Untrusted CA on that device
      What to check:

    • openssl s_client ... -showcerts

    • curl error text (often clearer)

  • curl: (60) SSL certificate problem: unable to get local issuer certificate
    Likely causes:

    • Missing intermediate (most common)

    • Server sending the wrong intermediate chain
      What to check:

    • OpenSSL chain output (-showcerts)

    • Compare across backends/IPs

  • ERR_CERT_DATE_INVALID / “certificate expired” / “not yet valid”
    Likely causes:

    • Cert expired

    • Cert validity start date is in the future

    • Device clock is wrong
      What to check:

    • Browser certificate validity dates

    • openssl x509 ... -dates

  • “Works in Chrome but fails on iOS Safari / apps”
    Likely causes:

    • Missing intermediate (Chrome cached it; iOS didn’t)

    • Alternate chain/cross-sign issue with older trust stores

    • IPv6 endpoint serving a different chain
      What to check:

    • curl -4 and -6

    • OpenSSL -showcerts (and compare with/without SNI)

  • Intermittent SSL errors (sometimes works, sometimes fails)
    Likely causes:

    • Multiple backends aren’t consistent (one has the right chain, another doesn’t)

    • DNS points to different endpoints by region/provider
      What to check:

    • curl --resolve against each backend IP

    • Repeat tests and note which IP fails


6) What to send HostBible Support (so we can help fast)

When you contact HostBible Support, include:

  • The exact URL/hostname that fails (copy/paste)

  • Where it fails: browser/app + device + OS version

  • The exact error message (screenshot is fine)

  • Output from these commands (paste as text):

    • curl -vI https://example.com (or the failing hostname)

    • openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null

  • If it’s intermittent: note the time and whether it happens on IPv4 vs IPv6

Security note: never share private keys. The commands above only fetch public certificate info.


Glossary (quick)

  • SAN (Subject Alternative Name): The list of hostnames a certificate is valid for.

  • Leaf certificate: The server certificate issued to your domain.

  • Intermediate certificate: Connects your leaf certificate to a trusted root.

  • Root certificate: Trusted anchor stored in the OS/browser trust store.

  • Certificate chain: Leaf + intermediate(s) leading up to a trusted root.

  • SNI (Server Name Indication): Lets a server choose the right certificate for a hostname on shared IPs.

  • TLS handshake: Negotiation step where protocol version, ciphers, and certificates are exchanged.

Did this answer your question?