BytePane

SSL Checker: Verify Your SSL Certificate & TLS Configuration

Security17 min read

Here's a surprising statistic: according to Qualys SSL Pulse January 2026 data, 92.6% of the top 100,000 websites now use HTTPS — yet 28.7% of those same sites fail to follow industry best practices, receiving reduced security grades due to configuration errors. Having a certificate isn't enough. What matters is whether it's configured correctly.

The SSL/TLS landscape has also changed fundamentally in 2026. On March 15, 2026, CA/Browser Forum Ballot SC-081 reduced the maximum certificate validity period from 398 days to 200 days. If you haven't set up automated renewal, your certificates will now expire roughly twice as often as they used to.

This guide covers how to check your SSL certificates using both online tools and command-line utilities, what the results mean, and how to fix the most common problems.

Key Takeaways

  • • As of March 15, 2026, maximum SSL certificate validity is 200 days — automated renewal via ACME (Let's Encrypt) or a cert manager is now effectively required
  • • Let's Encrypt holds 54.73% of all SSL certificate market share as of January 2026 per SSL Dragon analysis, making free, automated certs the clear default
  • • TLS 1.0 and 1.1 are blocked by all major browsers — support only TLS 1.2 and TLS 1.3
  • • Incomplete certificate chains are the #1 cause of SSL errors in API clients and mobile apps, even when browsers show the padlock
  • • ECDSA certificates offer equivalent security to 2x larger RSA keys — use RSA 2048+ or ECDSA P-256

What an SSL Certificate Actually Contains

An SSL/TLS certificate is an X.509 document (defined in RFC 5280) that binds a public key to a domain name. Understanding the certificate fields is essential for diagnosing problems.

# View certificate details with OpenSSL
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null   | openssl x509 -noout -text

# Key fields to check:
# Subject: CN=example.com          ← Primary domain
# Issuer: CN=R11, O=Let's Encrypt  ← Certificate Authority
# Validity:
#   Not Before: Feb  1 00:00:00 2026 GMT
#   Not After : Jul 31 23:59:59 2026 GMT  ← Expiry date
# Subject Alternative Name:
#   DNS:example.com, DNS:www.example.com  ← All covered domains
# Public Key Algorithm: id-ecPublicKey    ← ECDSA (preferred)
#   or rsaEncryption                      ← RSA
# Key Size: 256 bit (ECDSA P-256)
#   or 2048 bit (RSA)

# Get just the expiry date
echo | openssl s_client -connect example.com:443 2>/dev/null   | openssl x509 -noout -enddate
# notAfter=Jul 31 23:59:59 2026 GMT

# Check days until expiry (Linux)
echo | openssl s_client -connect example.com:443 2>/dev/null   | openssl x509 -noout -checkend 2592000  # 30 days in seconds
# Certificate will expire   → Renew now
# Certificate will not expire  → OK for 30 more days

SSL Certificate Market Share in 2026

The SSL certificate market is highly concentrated. According to SSL Dragon's January 2026 analysis of detected certificates across the web, three providers account for 93% of all certificates:

ProviderMarket ShareCostAutomationBest For
Let's Encrypt54.73%FreeACME (certbot, acme.sh)All public websites
GoDaddy34.62%$50–200/yrManual or APIBundled with hosting
Sectigo3.69%$70–300/yrAPI availableEnterprise, EV certs
DigiCert~2%$200–1000/yrCertCentral APIEnterprise, OV/EV
Cloudflare~1%Free (proxied)Fully automaticSites behind Cloudflare

For the vast majority of developers, Let's Encrypt is the correct choice. It's free, automatically renews via the ACME protocol, is trusted by all major browsers, and handles the 200-day validity requirement automatically. The only cases where you'd pay for a certificate: OV/EV validation requirements, certificates covering internal hostnames, or wildcard certs on platforms that don't support ACME DNS challenges.

TLS Version and Cipher Suite Support

A certificate being valid doesn't mean your TLS configuration is secure. The server also needs to use modern TLS versions and cipher suites. According to Qualys SSL Pulse January 2026, 94.8% of surveyed servers now support TLS 1.3 — but 6.2% still support the deprecated TLS 1.0.

TLS VersionStatusBrowser SupportWhy
TLS 1.3RecommendedAll modern browsers1-RTT handshake, mandatory PFS, fewer attack surfaces
TLS 1.2AcceptableAll browsersStill secure with correct cipher suites; needed for older clients
TLS 1.1DeprecatedBlockedDeprecated by RFC 8996 (2021); blocked in Chrome 84+, Firefox 74+
TLS 1.0 / SSL 3ProhibitedBlockedVulnerable to POODLE, BEAST, CRIME attacks
# Check which TLS versions a server supports
nmap --script ssl-enum-ciphers -p 443 example.com

# Or with OpenSSL (test specific versions)
openssl s_client -connect example.com:443 -tls1_3  # TLS 1.3 supported?
openssl s_client -connect example.com:443 -tls1_2  # TLS 1.2 supported?
openssl s_client -connect example.com:443 -tls1_1  # Should FAIL on secure servers
openssl s_client -connect example.com:443 -tls1    # Should FAIL on secure servers

# Check supported cipher suites with nmap
nmap --script ssl-enum-ciphers -p 443 example.com
# Outputs each cipher with a strength grade (A, B, C, F)
# Red flags: RC4, DES, 3DES, export ciphers, anonymous DH

# Nginx TLS 1.2+1.3 configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;

# Apache equivalent
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384...
SSLHonorCipherOrder off

Certificate Chain Issues: The #1 Hidden SSL Bug

This is the most common SSL configuration mistake: your certificate works in Chrome (you see the padlock) but API clients, curl, and mobile apps throw SSL errors. The cause is almost always an incomplete certificate chain.

Your certificate is issued by an intermediate CA, which is trusted by a root CA. Browsers have root CAs pre-installed and can sometimes fetch missing intermediates via AIA (Authority Information Access). But curl, most HTTP libraries, and mobile apps do not — they require the full chain to be served by your server.

# Check if the certificate chain is complete
openssl s_client -connect example.com:443 -showcerts 2>/dev/null

# Output shows each cert in the chain:
# Certificate chain
#  0 s:CN = example.com             ← Your leaf certificate (must have)
#    i:CN = R11, O=Let's Encrypt    ← Intermediate CA
#  1 s:CN = R11, O=Let's Encrypt    ← Intermediate CA cert (must have)
#    i:CN = ISRG Root X1, O=ISRG   ← Root CA (browsers have this built-in)

# If you only see Certificate 0, the intermediate is missing!

# Verify the chain with openssl verify
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt your-cert.pem
# Should output: your-cert.pem: OK

# Download and bundle Let's Encrypt intermediate manually
# (certbot handles this automatically)
cat your-domain.crt lets-encrypt-r11.crt > bundle.crt
# Then use bundle.crt as your certificate file in nginx/apache

# Nginx: ssl_certificate should include full chain
ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# fullchain.pem = cert + intermediates (the correct file to use)

Testing Chain Validity

# Full chain check — simulates what a strict TLS client sees
curl -v --cacert /etc/ssl/certs/ca-certificates.crt https://example.com 2>&1   | grep -E "SSL|TLS|certificate|verify"

# Common errors and what they mean:
# SSL certificate problem: unable to get local issuer certificate
#   → Intermediate certificate missing from server response
#
# SSL certificate problem: certificate has expired
#   → cert.notAfter is in the past — renew immediately
#
# SSL certificate problem: hostname mismatch
#   → cert.subjectAltName doesn't include this hostname
#   → check if you're using www vs non-www, or wildcard scope
#
# SSL certificate problem: self-signed certificate in certificate chain
#   → You're using a self-signed cert where a trusted cert is needed

# Check hostname matching specifically
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null   | openssl x509 -noout -ext subjectAltName
# X509v3 Subject Alternative Name:
#     DNS:example.com, DNS:www.example.com

Online SSL Checker Tools Compared

Several online tools provide comprehensive SSL/TLS analysis without needing command-line access.

ToolDepthGrade SystemBest For
Qualys SSL LabsVery deepA+ / A / B / C / FComprehensive audit; the industry standard
TestTLS.comDeepPass/Fail per testFast checks, works on any port
ssl.com checkerMediumStatus indicatorsQuick expiry/chain check
DigiCert checkerMediumPass/FailChain and installation validation

Qualys SSL Labs is the industry gold standard. Run it on every production domain. An A+ grade requires: TLS 1.2/1.3 only, forward secrecy cipher suites, HSTS with a long max-age, no weak cipher suites, and a complete certificate chain. A grade of B or lower means there's something worth fixing.

Note: Qualys SSL Labs only works for publicly accessible servers on port 443. For internal services or non-standard ports, openssl s_client and TestTLS.com (which supports custom ports) are better options.

Automating Certificate Renewal with Let's Encrypt

With the 200-day validity limit taking effect in 2026 and 47-day limits planned for 2029, manual certificate management is no longer tenable. Here's how to automate renewal with certbot (the most widely used ACME client):

# Install certbot (Ubuntu/Debian)
sudo apt install certbot python3-certbot-nginx

# Get a certificate for nginx (auto-configures nginx ssl)
sudo certbot --nginx -d example.com -d www.example.com

# Or standalone mode (stops your web server temporarily)
sudo certbot certonly --standalone -d example.com

# Or webroot mode (keeps web server running)
sudo certbot certonly --webroot -w /var/www/html -d example.com

# Certificates are stored in:
# /etc/letsencrypt/live/example.com/fullchain.pem  ← cert + chain
# /etc/letsencrypt/live/example.com/privkey.pem    ← private key

# Test renewal (dry run)
sudo certbot renew --dry-run

# Certbot auto-renewal is set up via systemd timer (check it):
sudo systemctl list-timers | grep certbot
# certbot.timer → runs certbot renew twice daily

# For Nginx, add a hook to reload after renewal:
# /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh
#!/bin/bash
systemctl reload nginx
# Alternative: acme.sh (pure shell, no dependencies)
curl https://get.acme.sh | sh

# Issue certificate
~/.acme.sh/acme.sh --issue -d example.com --webroot /var/www/html

# Install to nginx
~/.acme.sh/acme.sh --install-cert -d example.com   --key-file /etc/nginx/ssl/key.pem   --fullchain-file /etc/nginx/ssl/cert.pem   --reloadcmd "systemctl reload nginx"

# Docker: use Traefik or Caddy for automatic Let's Encrypt
# Caddy does TLS automatically with zero configuration:
# Caddyfile:
example.com {
    reverse_proxy localhost:3000
    # TLS managed automatically — no certbot needed
}

SSL Certificate Monitoring: Avoid Surprise Expirations

Certificate expiration is one of the most embarrassing infrastructure failures — it's entirely avoidable and still happens to major organizations regularly. Set up monitoring at multiple layers.

#!/bin/bash
# SSL expiry monitoring script — run via cron daily

DOMAIN="$1"
WARN_DAYS=30
CRITICAL_DAYS=7

EXPIRY=$(echo | openssl s_client -connect ${DOMAIN}:443 -servername ${DOMAIN} 2>/dev/null   | openssl x509 -noout -enddate 2>/dev/null   | cut -d= -f2)

EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s 2>/dev/null || date -jf "%b %d %T %Y %Z" "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))

if [ $DAYS_LEFT -le $CRITICAL_DAYS ]; then
  echo "CRITICAL: $DOMAIN expires in $DAYS_LEFT days ($EXPIRY)"
  exit 2
elif [ $DAYS_LEFT -le $WARN_DAYS ]; then
  echo "WARNING: $DOMAIN expires in $DAYS_LEFT days ($EXPIRY)"
  exit 1
else
  echo "OK: $DOMAIN expires in $DAYS_LEFT days ($EXPIRY)"
  exit 0
fi

# Add to crontab:
# 0 9 * * * /usr/local/bin/ssl-check.sh example.com || curl -s #   "https://hooks.slack.com/services/xxx" -d '{"text":"SSL expiring!"}'

For larger fleets, use a dedicated monitoring service. Several options integrate with PagerDuty or Slack alerts. The key threshold: alert at 30 days remaining, page at 7 days. With 200-day certificates, your renewal window is smaller than it used to be.

HSTS, HPKP, and Security Headers

A valid SSL certificate plus TLS 1.3 is necessary but not sufficient. Security headers instruct browsers on additional transport security requirements.

# HSTS (HTTP Strict Transport Security) — tells browsers HTTPS only
# Add to your web server configuration:

# Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

# Apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

# Node.js / Express
app.use((req, res, next) => {
  res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload')
  next()
})

# HSTS rollout strategy:
# Week 1: max-age=300              (5 min — test nothing breaks)
# Week 2: max-age=86400            (1 day)
# Week 3: max-age=604800           (1 week)
# Stable: max-age=31536000; includeSubDomains
# Final:  + preload (only after confirming ALL subdomains use HTTPS)

# ⚠️ Never add "preload" without first ensuring every subdomain
# serves HTTPS — there is no easy way to reverse a preload entry

# Check your HSTS header
curl -sI https://example.com | grep -i strict
# Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

# Note: HTTP Public Key Pinning (HPKP) is deprecated — do NOT use it.
# It was removed from Chrome 72 and Firefox 72 due to risk of bricking sites.

Checking SSL for Non-HTTPS Services

TLS isn't just for web servers on port 443. Email, SMTP, IMAP, PostgreSQL, and many other services support TLS. The same OpenSSL commands work for any port.

# Check TLS on non-HTTPS ports
# SMTP with STARTTLS (port 587)
openssl s_client -connect mail.example.com:587 -starttls smtp

# IMAP with STARTTLS (port 143)
openssl s_client -connect mail.example.com:143 -starttls imap

# IMAPS (port 993)
openssl s_client -connect mail.example.com:993

# PostgreSQL (port 5432)
openssl s_client -connect db.example.com:5432 -starttls postgres

# Redis TLS (port 6380)
openssl s_client -connect redis.example.com:6380

# Kubernetes API server (port 6443)
openssl s_client -connect k8s-api.example.com:6443

# For any port, same cert checks apply:
# -noout -dates   → expiry
# -noout -text    → full details
# -showcerts      → full chain

When working with TLS certificates in development, you'll often need to decode Base64-encoded certificate data. BytePane's Base64 decoder handles PEM certificate content (which is Base64-encoded DER), and the Hash generator can compute the SHA-256 fingerprint of a certificate for pinning comparisons.

Frequently Asked Questions

What does an SSL checker verify?

An SSL checker verifies: (1) certificate validity — whether the cert is not expired and issued by a trusted CA; (2) hostname matching — whether the cert covers the domain you're checking; (3) certificate chain — whether intermediate certificates are correctly served; (4) TLS protocol support — which TLS versions the server accepts; (5) cipher suites — which encryption algorithms are offered. Qualys SSL Labs grades all of these and assigns an overall letter grade.

What is the new SSL certificate validity limit in 2026?

Effective March 15, 2026, CA/Browser Forum Ballot SC-081 reduced maximum SSL/TLS certificate validity to 200 days (roughly 6.5 months), down from the previous 398-day maximum. Further reductions are planned: 100 days by 2027 and 47 days by 2029. Automated certificate renewal via ACME/Let's Encrypt is now effectively mandatory for production systems.

What is a certificate chain error?

A certificate chain error occurs when the server doesn't serve the full chain of intermediate certificates needed to connect your certificate to a trusted root CA. Browsers can sometimes recover by fetching intermediates via AIA, but API clients and mobile apps will hard-fail. Fix: download and bundle the intermediate certificates from your CA alongside the leaf certificate — in nginx, use fullchain.pem instead of cert.pem.

How do I check SSL certificate expiry from the command line?

Use OpenSSL: echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate. This prints the expiry date. For a 30-day warning check: add -checkend 2592000 — it exits with code 1 if expiry is within 30 days, making it easy to use in scripts and cron jobs.

What TLS version should my server use in 2026?

Support TLS 1.2 and TLS 1.3 only. TLS 1.0 and 1.1 are deprecated by RFC 8996 and blocked by all major browsers since 2020–2021. TLS 1.3 is the preferred version — it makes forward secrecy mandatory and reduces handshake latency. Per Qualys SSL Pulse January 2026, 94.8% of surveyed servers now support TLS 1.3.

What is HSTS and should I enable it?

HTTP Strict Transport Security (HSTS) instructs browsers to only connect via HTTPS for a specified duration, preventing protocol downgrade attacks. Enable with: Strict-Transport-Security: max-age=31536000; includeSubDomains. Start with a short max-age to test, then increase. Add preload only after confirming everything on your domain works over HTTPS.

What is the difference between DV, OV, and EV certificates?

DV (Domain Validation) verifies only that you control the domain — issuance is automated, takes seconds, and is free via Let's Encrypt. OV (Organization Validation) additionally verifies your organization's legal existence. EV (Extended Validation) was once distinguished by a green address bar, but that was removed from all browsers in 2019, making the extra cost hard to justify for most sites. For most developers, DV from Let's Encrypt is correct.

Developer Security & Networking Tools

Decode Base64-encoded certificate data with BytePane's Base64 decoder. Compute SHA-256 certificate fingerprints with the Hash Generator. Check JWT token expiry (the exp claim) with the JWT Decoder. Find your server's IP address with IP Lookup.

Open Hash Generator

Related Articles