Deploying HTTPS Correctly: Common Pitfalls and Fixes
You’ve probably heard the mantra “HTTPS everywhere” a dozen times this year, but the reality is that many sites still get it wrong. A half‑baked TLS setup can give users a false sense of security while leaving the door wide open for attackers. In this post I’ll walk through the most common mistakes I see in the field, why they matter, and how to fix them without pulling your hair out.
Why HTTPS Is Not a One‑Click Switch
When you flip the switch in your hosting control panel and see a padlock icon, it’s tempting to assume you’re done. The truth is that HTTPS is a layered protocol stack, and each layer has its own gotchas. Think of it like building a house: you can put a roof on a leaky foundation, but the house still won’t stand.
The Certificate Isn’t the Whole Story
Most developers focus on getting a certificate issued and forget about the rest of the TLS handshake. A certificate proves “who you are” to the browser, but the handshake also negotiates encryption algorithms, validates the certificate chain, and checks revocation status. If any of those steps are mis‑configured, browsers will either warn users or silently downgrade the connection.
Common Pitfall #1: Self‑Signed or Expired Certificates
What Happens
A self‑signed certificate will make every browser scream “Your connection is not private.” An expired cert does the same thing, but it’s harder to spot because the error message often just says “certificate has expired.” Both scenarios break user trust and can hurt SEO.
How to Fix It
- Use a free, automated service like Let’s Encrypt. Their client tools handle renewal automatically, so you don’t have to remember a 90‑day renewal cycle.
- Set up a monitoring job that checks the expiry date of your certs and alerts you a week before they lapse. A simple cron script that runs
openssl x509 -noout -dates -in /path/to/cert.pemis enough. - If you must use a self‑signed cert for internal testing, make sure it is never served to the public internet. Use a separate domain or a VPN‑only subdomain.
Common Pitfall #2: Incomplete Certificate Chain
What Happens
When a server sends only its leaf certificate without the intermediate certificates, some browsers will still work (they can fetch the missing pieces) but others will show a “certificate not trusted” error. This is especially common with certificates issued by newer CAs that require a chain of two or three intermediates.
How to Fix It
Combine your leaf certificate with the intermediate bundle provided by the CA into a single file. In Apache you’d use SSLCertificateFile for the combined file and SSLCertificateKeyFile for the private key. In Nginx, the ssl_certificate directive should point to the concatenated file, while ssl_certificate_key points to the key.
Common Pitfall #3: Weak Cipher Suites
What Happens
Older browsers and some corporate firewalls still support legacy ciphers like RC4 or 3DES. If you leave those enabled, an attacker can force a downgrade and sniff the traffic. Even if you think “no one uses those ciphers anymore,” the risk is real for sites that serve a global audience.
How to Fix It
- Use the Mozilla SSL Configuration Generator as a starting point. Choose the “intermediate” profile for a good balance of compatibility and security.
- Disable SSLv2 and SSLv3 outright. They are broken beyond repair.
- Prefer forward‑secrecy ciphers (ECDHE) so that even if a private key is compromised later, past sessions stay safe.
- Test your server with
sslscanor the Qualys SSL Labs test. Aim for an A or A+ rating.
Common Pitfall #4: Ignoring HTTP Strict Transport Security (HSTS)
What Happens
Without HSTS, a user who types “example.com” into the address bar may still be served over plain HTTP before the browser learns to upgrade to HTTPS. This opens a window for a man‑in‑the‑middle attack.
How to Fix It
Add the header Strict-Transport-Security: max-age=31536000; includeSubDomains; preload to your HTTPS responses. The max-age value is in seconds (one year in this example). If you’re confident your entire site is HTTPS‑only, submit the domain to the HSTS preload list so browsers start with HTTPS from day one.
Common Pitfall #5: Mixed Content
What Happens
A page loaded over HTTPS that pulls scripts, images, or styles over HTTP triggers “mixed content” warnings. Modern browsers will block active mixed content (like scripts) and may still display passive content (like images) with a warning badge. This not only looks unprofessional but can break functionality.
How to Fix It
- Scan your codebase for hard‑coded
http://URLs. Tools likegrep -R "http://"can help. - Use protocol‑relative URLs (
//example.com/script.js) or, better yet, always usehttps://. - For third‑party assets, make sure the provider offers HTTPS. If not, consider self‑hosting the asset or finding an alternative.
Common Pitfall #6: Not Enforcing HTTPS on the Server
What Happens
Even with a perfect TLS config, if your server still accepts plain HTTP connections, users can be lured to the insecure version. Some sites set up a redirect from HTTP to HTTPS, but forget to handle edge cases like subdomains or non‑standard ports.
How to Fix It
Configure a blanket redirect at the web server level:
- Apache:
RewriteEngine Onfollowed byRewriteCond %{HTTPS} offandRewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]. - Nginx:
return 301 https://$host$request_uri;inside theserverblock that listens on port 80.
Make sure the redirect is a 301 (permanent) so search engines update their index.
A Personal Tale: The Time I Forgot to Restart
I once rolled out a fresh TLS config on a client’s production server, double‑checked the cert chain, hardened the ciphers, and even added HSTS. Everything looked perfect in the Qualys report. Then a user called in complaining that the site still showed a “not secure” warning. After a quick look, I realized I had edited the wrong virtual host file. The old host was still serving the stale cert, and I hadn’t restarted the service. A quick systemctl reload nginx solved it, but the lesson stuck: automation and verification go hand‑in‑hand. Always run a final sanity check after a reload.
Checklist for a Bullet‑Proof HTTPS Deployment
- [ ] Certificate issued by a trusted CA, auto‑renewed, and not expired.
- [ ] Full certificate chain served (leaf + intermediates).
- [ ] Only strong TLS versions (TLS 1.2+), weak ciphers disabled.
- [ ] HSTS header set with a long max‑age and preload flag if possible.
- [ ] No mixed content on any page (use automated scanners).
- [ ] HTTP traffic redirected to HTTPS with a 301 status.
- [ ] Monitoring in place for cert expiry and TLS health.
Deploying HTTPS correctly is a bit of a marathon, not a sprint. The effort pays off in user trust, better SEO, and a reduced attack surface. Take the time to audit each layer, automate what you can, and you’ll sleep better at night knowing your site is truly secure.
- → Automating Security Scans: Plugging Safety into Your CI/CD Pipeline
- → What Every Business Should Know About GDPR Compliance for Web Apps
- → Securing Third-Party Scripts Without Slowing Down Your Site
- → Beginner's Guide to Threat Modeling for Web Applications
- → From Vulnerable to Resilient: Securing Your Site's Login Flow