Why HTTPS Errors Happen After Installation
Installing an SSL certificate does not always mean HTTPS works immediately or without issues. Many server configurations, content management systems, and applications have assumptions built in that favour HTTP, and these can cause problems even after a valid certificate is in place.
Common problems include mixed content warnings, certificate chain errors, domain mismatch, expired certificates, and redirect loops. Each has a specific cause and a specific fix. Understanding what each error actually means narrows down the troubleshooting approach considerably.
If you are setting up Let's Encrypt for the first time, the Let's Encrypt setup guide for Ubuntu covers the initial installation process, while the auto-renewal setup guide covers how to keep certificates valid without manual intervention.
Certificate Chain Errors
A certificate chain error means the server is sending the SSL certificate but not the intermediate certificates that browsers need to verify the certificate back to a trusted root certificate authority. Browsers typically handle this gracefully by downloading missing intermediates, but some clients and older browsers fail to connect entirely.
When the chain is incomplete, visitors using certain devices or older browsers may see connection errors even though the certificate itself is valid. This is a configuration issue on the server side, not a problem with the certificate itself.
Check the certificate chain using OpenSSL.
openssl s_client -connect yourdomain.com:443 -showcerts
This command shows all certificates in the chain. You should see the server certificate first, followed by one or more intermediate certificates, and a root certificate at the end. If the chain ends at an intermediate without a root, the root is missing from the server configuration.
For Apache, configure the certificate chain by appending the intermediate certificates to your certificate file.
cat your_domain.crt intermediate-cert.crt > bundled.crt
Update the Apache configuration to point to the bundled file.
SSLCertificateFile /etc/ssl/certs/bundled.crt
SSLCertificateKeyFile /etc/ssl/private/your_domain.key
In Nginx, use the ssl_trusted_certificate directive to provide the chain separately from the server certificate.
ssl_certificate /etc/ssl/certs/bundled.crt;
ssl_trusted_certificate /etc/ssl/certs/chain.crt;
Let's Encrypt certificates typically do not have chain issues because the chain is served correctly by default, but it is worth verifying with the OpenSSL command above after any new installation.
If you are using Certbot with Apache on Ubuntu, the automatic configuration usually handles the certificate chain correctly. Manual configuration is more common when setting up certificates through other methods or when custom server configurations are in place.
Mixed Content Warnings
Mixed content happens when an HTTPS page loads resources such as images, scripts, stylesheets, or iframes over HTTP. The page is technically served over HTTPS, but some of its content comes from insecure sources. Modern browsers block mixed content by default, which means parts of your page may not load, or the padlock icon may not appear.
These warnings indicate that while the page connection is encrypted, some of its content is not. This matters because an attacker could intercept and modify the insecure resources, even though the main page is served over HTTPS. Mixed content is a security issue as well as a configuration problem.
Use the browser developer tools to identify mixed content errors. In Chrome, open DevTools with F12, go to the Console tab, and look for messages like:
Mixed Content: The page at 'https://example.com' was loaded over HTTPS,
but requested an insecure resource 'http://example.com/image.jpg'.
This request is blocked; it must be served over HTTPS.
The Console will list each resource that is being loaded over HTTP. Make a note of all of them before starting the fix, because some may be in templates, theme files, or plugin code rather than in page content itself.
Fix mixed content by updating all resource URLs to use HTTPS. Search your database and code for hardcoded HTTP URLs.
-- Find HTTP URLs in WordPress database
SELECT * FROM wp_posts WHERE post_content LIKE '%src="http://%';
In WordPress, use WP-CLI to replace HTTP URLs with HTTPS across the database.
wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' --skip-tables=wp_options
Be careful when running search-and-replace on a live site. Test on a staging environment first, and ensure you have a current backup before making database-wide changes. Running a blanket search-and-replace across all tables can cause issues if your site stores serialized data or absolute URLs in unexpected places.
Use protocol-relative URLs as a temporary measure, but switching to explicit HTTPS is the better long-term solution.
<!-- Avoid protocol-relative URLs -->
<script src="//cdn.example.com/script.js"></script>
<!-- Use explicit HTTPS -->
<script src="https://cdn.example.com/script.js"></script>
If you use external scripts or CDN resources, verify they support HTTPS before linking to them. Most major CDN providers do, but custom or less common resources may need to be checked.
Certificate Mismatch Errors
Certificate mismatch means the certificate's Common Name or Subject Alternative Name does not include the domain you are accessing it with. This commonly happens when you install a certificate for www.example.com but access the site at example.com, or when you access by IP address, or when a certificate was issued for a different subdomain entirely.
A mismatch error does not necessarily mean your certificate is invalid. It means the certificate was issued for a different domain than the one you are currently using. The browser cannot trust a certificate for the wrong domain because it has no way to verify that you own or control that domain.
Check what the certificate was issued for using OpenSSL.
openssl s_client -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -subject -ext subjectAltName
Make sure the output includes the exact domain you are using to access the site. If the certificate was issued for www.example.com and you access it as example.com, either install a certificate covering both or redirect one to the other.
For multiple subdomains, use a wildcard certificate or list each subdomain as a Subject Alternative Name during certificate creation.
# With Let's Encrypt, request a certificate covering both example.com and www.example.com
sudo certbot --nginx -d example.com -d www.example.com
If you are using Nginx as a reverse proxy with HTTPS endpoints, the reverse proxy setup guide covers how to configure SSL certificates for proxy configurations correctly, which can help avoid mismatch issues in more complex server setups.
Expired Certificates
An expired certificate is exactly what it sounds like: the certificate validity period has passed and browsers refuse to connect to sites presenting it. If your site worked yesterday and shows this error today, check the certificate expiry date first.
echo | openssl s_client -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -dates
The output shows notBefore and notAfter dates. If notAfter is in the past, the certificate has expired and needs renewal.
Let's Encrypt certificates expire after 90 days. If you installed Let's Encrypt manually without setting up auto-renewal, renew it now.
sudo certbot renew
Check that the Certbot cron job or systemd timer is active so renewals happen automatically going forward.
sudo systemctl status certbot.timer
sudo certbot renew --dry-run
The dry-run confirms renewal works without actually issuing a new certificate. If it fails, check that your domain DNS is still pointing to the server and that port 80 is accessible.
Proper auto-renewal setup means you do not have to remember to renew certificates manually. The Let's Encrypt auto-renewal guide walks through the full process including cron jobs and systemd timers.
Redirect Loops After HTTPS Installation
A redirect loop occurs when the server redirects HTTPS to HTTP, or HTTP to HTTPS, which then redirects back, creating an infinite loop. The browser shows an error after too many redirects and the page never loads.
Redirect loops usually happen because of conflicting redirect rules. The server configuration may have HTTPS enforcement, while the application configuration or .htaccess file may have a different rule. The result is that each redirect triggers another redirect in the opposite direction.
In Apache, check your .htaccess file for redirect rules that conflict with each other or with HTTPS enforcement in the main configuration.
# Force HTTPS in .htaccess
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If you also have HTTPS enforcement in the VirtualHost configuration, the two rules will conflict and produce a redirect loop. Remove one or the other. Pick one place to handle all HTTPS redirection and keep it consistent.
In Nginx, check for conflicting redirect rules across server blocks.
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
# Ensure this block does not redirect back to HTTP
}
WordPress sites often have this problem in the Site URL and Home settings. If these are set to HTTP when HTTPS is enabled, WordPress redirects to HTTP indefinitely.
# Check WordPress URLs in wp-config.php
define('WP_HOME', 'https://example.com');
define('WP_SITEURL', 'https://example.com');
Update these to HTTPS and clear any caching plugins or server-level cache that may be serving stale redirects. Caching is a common reason why redirect loops persist even after the configuration has been fixed.
Wrong or Missing DH Parameters
Some older clients require Diffie-Hellman parameters for the SSL handshake. If you see errors like no shared cipher or dh key too small, generate new DH parameters and ensure your server is configured to use them.
Diffie-Hellman parameters are used in the key exchange process during the SSL handshake. Older servers or clients may expect these parameters to be present, and without them, the handshake fails even if the certificate is valid.
sudo openssl dhparam -out /etc/ssl/private/dhparams.pem 2048
Generating DH parameters can take a few minutes on slower hardware. Once complete, reference the file in your Nginx configuration.
ssl_dhparam /etc/ssl/private/dhparams.pem;
In Apache, add the DH parameters to your SSL configuration.
SSLOpenSSLConfCmd DHParameters "/etc/ssl/private/dhparams.pem"
Using 2048-bit DH parameters is a reasonable minimum for most setups. If you are supporting very old clients that require smaller parameters, be aware that shorter DH keys reduce the effective security of the connection.
Certificate Works but Padlock Shows as Insecure
Even with a valid certificate, the padlock may show as not fully secure if there are issues with the certificate chain, mixed content, or missing security headers. The padlock icon is the browser's way of indicating whether a page is fully served over a secure connection, and it checks several things beyond just the certificate validity.
Use a diagnostic tool to check any HTTPS-related issues on a specific URL. These tools check certificate validity, chain completeness, mixed content, and redirect issues. Run them on your key pages after any HTTPS configuration change to confirm everything is working correctly.
Beyond the padlock itself, it is worth reviewing your server's security headers. Adding Strict-Transport-Security, Content-Security-Policy, and X-Content-Type-Options headers reinforces HTTPS and reduces the risk of certain attacks. Strict-Transport-Security, in particular, tells browsers to only connect over HTTPS and helps protect against downgrade attacks.
These headers are part of a broader approach to web application security, where HTTPS is a foundation rather than a complete solution on its own.
Testing Your HTTPS Configuration
After making any changes to your SSL configuration, test the result thoroughly before considering the job done. Check all major pages of your site, including those with forms, media, and third-party integrations.
Test from multiple locations and browsers if possible. Some issues appear only in specific client configurations or older browser versions. What works in Chrome on a modern laptop may still fail in Safari on an older device.
Pay particular attention to pages that load external resources such as payment gateways, analytics scripts, advertising tags, or embedded media. These often have their own HTTPS requirements and may be the source of warnings even when your own configuration is correct.
Keep a record of what you changed and why. This makes it easier to troubleshoot future issues or roll back changes if something breaks. Documenting your SSL configuration is particularly useful when you need to renew certificates or make server changes months or years later.
When testing, check both the homepage and inner pages of your site. Certificate issues can sometimes affect specific subdomains or paths if the configuration was applied inconsistently.
When HTTPS Issues Need Professional Attention
Many HTTPS errors can be resolved by following the steps above, but some situations benefit from hands-on server access and experience with the specific platform involved.
Consider reaching out for help if you have made configuration changes and the issues persist, if you are unsure which server configuration file controls HTTPS, if your hosting provider uses a non-standard control panel that makes direct configuration difficult, or if the site uses multiple subdomains or complex proxy setups that make troubleshooting harder.
Before getting in touch, gather some basic information. Note the exact error message you see in the browser, the domain name and hosting provider, the server software in use (Apache, Nginx, or another), and any recent changes made to the site or server. This helps narrow down the problem faster.