Chapter 7

Troubleshooting HTTPS

Mixed content, cert mismatch, expiry, chain errors.

Learning objectives

  • Map browser errors to likely causes
  • Fix mixed content, expiry, and hostname mismatch
  • Use openssl and curl for certificate debugging

Symptom → cause cheat sheet

What users seeLikely causeFirst check
“Your connection is not private”Expired cert, bad chain, or MITMExpiry and chain in browser or openssl s_client
Certificate name mismatchHostname not in SANCompare URL to cert SANs
Padlock broken / mixed contentHTTPS page loads HTTP assetsBrowser dev tools → Console
ERR_TOO_MANY_REDIRECTSHTTP↔HTTPS loopcurl -I trace redirect chain
502 Bad GatewayPHP-FPM down or wrong socketsystemctl status php8.3-fpm

Diagnostic commands

# Certificate presented on port 443
openssl s_client -connect www.workshopco.ca:443 -servername www.workshopco.ca < /dev/null

# Follow redirects, show headers only
curl -I -L https://www.workshopco.ca

# Check expiry dates Certbot knows about
sudo certbot certificates

Worked example — mixed content after HTTPS migration

Workshop Co. enables HTTPS but the classes page still references http://www.workshopco.ca/images/bench.jpg. Browsers block or warn because active content on an HTTPS page must also be HTTPS.

Fix: Use relative URLs (/images/bench.jpg) or https:// everywhere. Search CMS/theme for hard-coded http://. Add Content-Security-Policy: upgrade-insecure-requests as a safety net during migration.

Do not disable warnings

Telling customers to “click Advanced → proceed anyway” trains bad habits. Fix the certificate or content issue instead.

Worked example — expired staging cert

staging.workshopco.ca shows expiry errors. Production is fine. Staging uses a separate cert that failed renewal because DNS pointed staging to a new IP but Certbot still ran on the old server.

Fix: Run Certbot where port 80/443 for staging actually terminates, or fix DNS. Verify with certbot renew --dry-run -d staging.workshopco.ca.

Try it yourself — triage

A colleague reports: “HTTPS works in Chrome on Mac but fails on an older Android phone with chain error.” List three things you would compare between the two clients.

Answer
  1. Whether the server sends the full intermediate chain (openssl s_client output)
  2. Root/intermediate trust on older Android ( outdated CA store )
  3. Whether they hit a CDN vs origin with different chain config

Redirect loop puzzle

Nginx has: (1) port 80 → 301 to HTTPS; (2) port 443 if ($host = workshopco.ca) { return 301 https://www.workshopco.ca$request_uri; }; (3) load balancer also redirects HTTP to HTTPS. Users get too many redirects. What is a cleaner approach?

Answer

Use separate server blocks instead of nested if redirects. One block for apex → www on 443, one for www content. Ensure only one layer (LB or Nginx) performs HTTP→HTTPS redirect.

Quick quiz

  1. What is mixed content?
  2. Which tool shows the certificate chain from the command line?
  3. 502 from Nginx often means what upstream problem?
Answers
  1. HTTPS page loading subresources over plain HTTP.
  2. openssl s_client
  3. PHP-FPM or proxy_pass backend unreachable or crashed.