WordPress SSL problems fall into distinct categories, each caused by something different and requiring a different fix. Installing an SSL certificate on your server is only the first step. What breaks after that depends on how your site was built, what plugins are active, whether you use Cloudflare, and whether WordPress’s own database still contains hardcoded HTTP URLs.
The most common mistake when troubleshooting WordPress SSL is applying fixes in random order without identifying which specific problem you have. A redirect loop fix applied to a mixed content problem does nothing. A database search-replace applied before confirming the SSL certificate is working correctly can lock you out. This guide identifies each problem first, then applies the targeted fix.
This guide covers five distinct WordPress SSL problems: the redirect loop, mixed content errors, the Cloudflare Flexible SSL trap, certificate errors from misconfigured hosts, and the common post-migration SSL failures. Each has a precise cause and a clean fix.
Step Zero: Confirm Your SSL Certificate Is Actually Working
Before troubleshooting any WordPress-specific SSL issue, confirm the certificate itself is installed and valid. A WordPress SSL problem and a server SSL problem look similar in the browser but require completely different fixes. Applying WordPress fixes to a server certificate problem wastes time.
Test the certificate directly: visit https://yourdomain.com directly in a browser. If you see a padlock with no warning, the certificate is installed correctly and the problem is WordPress configuration. If you see a full-page certificate error (red warning, expired certificate, wrong domain), the problem is the certificate itself, not WordPress.
For a thorough check, run your domain through the SSL Labs test at ssllabs.com/ssltest. This confirms the certificate chain is complete, the certificate covers your domain, and TLS is configured correctly. Fix any issues the SSL Labs test identifies before touching WordPress configuration.
| What you see | What it means | Where to fix it |
| Full-page red certificate error in browser | Certificate problem on the server | Fix at the hosting level: install, renew, or reconfigure the certificate. See the SSL certificate guides in this series. |
| Site loads on HTTP only, no padlock | No SSL redirect configured | Fix in WordPress: wp-config.php, .htaccess, or WordPress Settings. |
| Padlock with warning / not fully secure | Mixed content: some resources load over HTTP | Fix in WordPress database and theme files. |
| ERR_TOO_MANY_REDIRECTS | Redirect loop: multiple systems fighting over HTTP/HTTPS | Fix by identifying which system is causing the double redirect. |
| Padlock present but site broken (missing styles, images) | Mixed content blocked by browser | Fix in WordPress database and theme files. |
Issue 1: ERR_TOO_MANY_REDIRECTS After Installing SSL
A redirect loop is the most common problem after installing an SSL certificate on WordPress. The browser follows a redirect from HTTP to HTTPS, then gets sent back to HTTP, then redirected to HTTPS again, and loops until it gives up. The cause is always two systems both trying to handle the redirect and conflicting with each other.
Root cause A: WordPress URL settings still on HTTP
WordPress stores the site URL and home URL in the database. If these still say http:// after the certificate is installed, WordPress sends HTTP headers for page resources even while the web server is redirecting all HTTP to HTTPS. The fix:
- Log into WordPress admin panel
- Go to Settings, then General
- Change both WordPress Address (URL) and Site Address (URL) from http:// to https://
- Click Save Changes
If you cannot log in because the redirect loop blocks the admin panel, update the URLs directly in the database or via wp-config.php:
| # Add to wp-config.php (before the ‘Happy Blogging’ comment):
define(‘WP_HOME’, ‘https://yourdomain.com’); define(‘WP_SITEURL’, ‘https://yourdomain.com’); |
Root cause B: Cloudflare Flexible SSL creating a redirect loop
This is the single most common cause of WordPress redirect loops among sites using Cloudflare, and it is caused by a specific combination that is easy to accidentally create. Here is the exact mechanism:
When Cloudflare SSL is set to Flexible, Cloudflare connects to your origin server over plain HTTP. Your origin server, if it has an SSL certificate and an HTTP-to-HTTPS redirect rule in .htaccess, receives the HTTP request from Cloudflare and immediately redirects it to HTTPS. Cloudflare receives the redirect response, connects back to your origin over HTTP again (because the mode is Flexible), gets redirected again, and the loop continues indefinitely.
Cloudflare Flexible SSL mode is the cause of a large proportion of WordPress redirect loops on Cloudflare-proxied sites. The fix is not to add code to wp-config.php or disable the .htaccess redirect. The fix is to change Cloudflare’s SSL mode to Full or Full (Strict) in the Cloudflare dashboard under SSL/TLS, Overview. Flexible mode should not be used for any site with an SSL certificate installed on the origin server.
If your origin server does not yet have an SSL certificate installed, the correct order of operations is: install an SSL certificate on the origin server first, then change Cloudflare to Full or Full (Strict). Do not activate an HTTP-to-HTTPS redirect until both Cloudflare and the origin are configured for HTTPS.
Root cause C: Multiple redirect rules conflicting
A redirect loop can occur when several places are all trying to redirect HTTP to HTTPS simultaneously: the .htaccess file, a WordPress plugin (Really Simple SSL, WP Force SSL), the hosting control panel’s force HTTPS toggle, and Cloudflare page rules. Each one trying to handle the redirect creates cascading conflicts.
The cleanest fix: use only one redirect mechanism. Remove or disable the others. The preferred approach for an Apache server is a single .htaccess rule:
| # Add to .htaccess, before the WordPress rewrite rules:
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] |
For Nginx, use a separate server block listening on port 80 that returns a 301 redirect to HTTPS. Do not duplicate this in multiple locations. One redirect rule, one place.
Disable any redirect plugins (Really Simple SSL, Redirection, WP Force HTTPS) and the hosting control panel’s force HTTPS toggle while testing. Having the .htaccess redirect plus a plugin redirect plus a Cloudflare page rule all running simultaneously is a common cause of loops that are difficult to untangle. Start with one mechanism, confirm it works, then leave it as the only one.
Issue 2: Mixed Content Errors and the Broken Padlock
Mixed content occurs when a page is served over HTTPS but some of its resources (images, scripts, stylesheets, iframes) are referenced with http:// URLs. Modern browsers block active mixed content (scripts and stylesheets) entirely. Passive mixed content (images) may be loaded with a warning. Both produce the broken padlock or the ‘Not fully secure’ indicator.
Finding mixed content
In Chrome: open the page, press F12 to open developer tools, go to the Console tab. Mixed content errors appear as red or yellow warnings showing the specific HTTP URL being blocked. Write down the URLs shown. You need to know whether they are your own site’s content (fixable via database update) or third-party embeds (requires updating the embed source or using a proxy).
The free tool Why No Padlock (whynopadlock.com) scans a URL and lists all mixed content resources without needing browser developer tools.
The correct fix: database search-replace
The root cause of most mixed content is that WordPress’s database still contains http:// in URLs stored during the site’s HTTP period: post content, theme options, widget data, menu items, and SEO plugin settings all store absolute URLs. A database search-replace changes all stored http://yourdomain.com references to https://yourdomain.com in one operation.
The recommended tool is WP-CLI’s search-replace command, which is precise, fast, handles serialized data correctly, and does not use output buffering:
| # Run from your server via SSH or a hosting terminal:
$ wp search-replace ‘http://yourdomain.com’ ‘https://yourdomain.com’ –skip-columns=guid
# For a dry run first (shows what would change without changing anything): $ wp search-replace ‘http://yourdomain.com’ ‘https://yourdomain.com’ –dry-run –skip-columns=guid
# After running, flush object cache and regenerate permalinks: $ wp cache flush $ wp rewrite flush
# The –skip-columns=guid option preserves GUID values which should not change. |
If WP-CLI is not available, the Better Search Replace plugin (by Delicious Brains) performs the same operation through the WordPress admin panel. It handles serialized data correctly, which is important for theme options and plugin settings stored as PHP serialized arrays.
Do not use a simple SQL replace statement directly in phpMyAdmin for this purpose. WordPress stores some data as PHP serialized strings (for example, a:2:{s:3:”url”;s:22:”http://yourdomain.com”…}). A direct SQL replace changes the URL string length without updating the length prefix in the serialization, which corrupts the data and breaks theme options and plugin settings. WP-CLI and Better Search Replace both handle serialized data correctly.
Hardcoded URLs in theme files
Some themes hardcode http:// in PHP template files rather than using WordPress functions like home_url() or site_url(). A database search-replace will not fix these because they are in PHP files, not the database. Use a file search across the theme directory to find hardcoded http:// references:
| # Search theme files for hardcoded http URLs:
$ grep -r ‘http://yourdomain.com’ /path/to/wp-content/themes/your-theme/
# Replace them with the HTTPS version or with WordPress URL functions: # Instead of: <img src=”http://yourdomain.com/wp-content/uploads/image.jpg”> # Use: <img src=”<?php echo esc_url(site_url(‘/wp-content/uploads/image.jpg’)); ?>”> |
Third-party embeds with HTTP sources
YouTube embeds, social media widgets, analytics scripts, ad networks, and external resources that use http:// cannot be fixed by a database search-replace. They require either updating the embed code to use https:// (most providers support this; use the https embed URL from the provider’s embed interface), using a content security policy upgrade-insecure-requests header that tells the browser to try upgrading them automatically, or removing the embed if no HTTPS version is available.
Issue 3: Certificate Errors from WordPress-Specific Hosting Configurations
Let’s Encrypt auto-renew not working on cPanel
cPanel’s AutoSSL uses Let’s Encrypt and should renew certificates automatically. Renewal failures commonly occur when: the domain’s DNS is no longer pointing to the cPanel server (common after adding Cloudflare), the domain validation check is blocked by a security plugin that returns 403 errors for the .well-known directory, or the cPanel AutoSSL job fails silently.
Check the AutoSSL status in cPanel under Security, SSL/TLS Status. Run AutoSSL manually by clicking Run AutoSSL. If it shows a validation failure, the most common fix is adding an exception in your security plugin for /.well-known/acme-challenge/ paths to ensure the Let’s Encrypt validation file can be accessed. In .htaccess:
| # Add before other redirect rules in .htaccess:
RewriteEngine On RewriteRule ^.well-known/acme-challenge/ – [L]
# This prevents any other redirect or security rules from # blocking the Let’s Encrypt domain validation check. |
Wrong certificate domain coverage
A certificate that covers yourdomain.com but not www.yourdomain.com (or vice versa) produces NET::ERR_CERT_COMMON_NAME_INVALID for the uncovered version. Check in the hosting control panel which domains are covered by the installed certificate. Either install a certificate that covers both variants (most CAs include both in a SAN) or ensure the redirect from one to the other happens before HTTPS is negotiated (which is not possible without a certificate for the first domain as well). The clean solution is a certificate that includes both yourdomain.com and www.yourdomain.com as SANs.
Issue 4: SSL Issues After Migrating WordPress to a New Host or Domain
Migrating WordPress from one host to another, or changing the domain, is a common trigger for SSL issues because WordPress stores URLs throughout its database. A migration that uses a database backup from the old site carries all the old URLs with it.
Complete URL replacement after migration
After migrating, the database contains the old domain’s URLs. Run the search-replace for both the old domain and any localhost or staging URLs that were used during development:
| # Replace old domain with new domain:
$ wp search-replace ‘https://olddomain.com’ ‘https://newdomain.com’ –skip-columns=guid
# Also replace any HTTP version of old domain: $ wp search-replace ‘http://olddomain.com’ ‘https://newdomain.com’ –skip-columns=guid
# If migrating from a local or staging environment: $ wp search-replace ‘http://localhost’ ‘https://newdomain.com’ –skip-columns=guid $ wp search-replace ‘https://staging.olddomain.com’ ‘https://newdomain.com’ –skip-columns=guid
# Regenerate permalinks after the replace: $ wp rewrite flush –hard |
wp-config.php still referencing old URLs
If wp-config.php has hardcoded WP_HOME or WP_SITEURL definitions from the old migration, they override the database values. Check wp-config.php for define statements referencing the old domain and update them to the new domain, or remove them entirely to allow the database values to control the URLs.
Issue 5: Really Simple SSL Plugin Creating Problems
Really Simple SSL is frequently recommended as the first solution for WordPress mixed content and SSL issues. It is useful for quickly activating basic HTTPS settings, but it uses PHP output buffering to rewrite content at runtime rather than fixing the underlying database URLs. This creates several problems worth understanding.
- Performance impact on first loads: Output buffering scans every page’s HTML before serving it and replaces http:// with https:// dynamically. The first load of each uncached page incurs this overhead. With caching active, cached pages are already rewritten, so subsequent loads are not affected, but the first-load penalty exists.
- Caching plugin conflicts: Caching plugins cache the page content before or after Really Simple SSL rewrites it, depending on the execution order. This can produce inconsistent results where some cached pages have rewritten URLs and others do not, or where the rewrite conflicts with the cache invalidation logic.
- It does not fix the database: The database still contains http:// URLs. If Really Simple SSL is deactivated, all mixed content returns. The database search-replace is the permanent fix; Really Simple SSL is a temporary workaround that creates an ongoing dependency.
Use Really Simple SSL or a similar plugin to quickly enable the WordPress HTTPS settings (updating WordPress Address and Site Address to https://) and to identify mixed content, then run the WP-CLI search-replace or Better Search Replace to fix the database URLs permanently. Once the database is clean and all URLs are HTTPS, you can deactivate Really Simple SSL if you prefer not to run it permanently.
Verification: Confirming Everything Is Fixed
After applying any of the fixes above, verify the complete SSL configuration is correct before considering the issue resolved.
- Open the site in a browser and confirm the padlock appears with no warning on the homepage.
- Navigate to several internal pages (blog posts, category pages, the contact page, any checkout or login pages) and confirm the padlock is clean on each.
- Open Chrome developer tools (F12), go to Console, and confirm no mixed content warnings appear on any page.
- Run the site through Why No Padlock (whynopadlock.com) or SSL Labs (ssllabs.com/ssltest) for a programmatic check.
- Confirm redirects work correctly: typing http://yourdomain.com in the browser address bar should redirect to https://yourdomain.com with a 301.
- If using Cloudflare, confirm the SSL mode is Full or Full (Strict) in the Cloudflare dashboard.
- Clear all caches: WordPress page cache, object cache, CDN cache, and browser cache, then retest.
Frequently Asked Questions
Why is my WordPress site showing a redirect loop after I installed SSL?
The most common causes are: Cloudflare SSL is set to Flexible mode (causing Cloudflare to connect to your origin over HTTP while your origin redirects that HTTP request back to HTTPS), multiple redirect mechanisms conflicting (an .htaccess rule plus a WordPress plugin plus a hosting control panel toggle all redirecting simultaneously), or WordPress’s Site URL and Home URL settings still contain http:// causing WordPress to generate HTTP URLs while the server redirects to HTTPS. Identify which cause applies before applying fixes: check your Cloudflare SSL mode first, then check Settings, General in WordPress, then check .htaccess.
What is mixed content and how do I fix it in WordPress?
Mixed content means a page is served over HTTPS but references some resources (images, scripts, stylesheets) using http:// URLs. Browsers block active mixed content entirely and warn about passive mixed content. The root cause in WordPress is usually the database still containing http:// URLs from when the site ran on HTTP. The correct fix is a WP-CLI search-replace command (wp search-replace ‘http://yourdomain.com’ ‘https://yourdomain.com’ –skip-columns=guid) or the Better Search Replace plugin, both of which handle WordPress’s serialized data correctly. Hardcoded http:// URLs in theme PHP files must be fixed in the files themselves.
Should I use Really Simple SSL to fix my WordPress SSL issues?
Really Simple SSL is useful for quickly changing WordPress’s URL settings from HTTP to HTTPS and for temporarily suppressing mixed content warnings. It is not a permanent fix: it rewrites content at runtime using output buffering rather than fixing the database URLs, and deactivating the plugin brings the mixed content back. Use it as a diagnostic and quick-fix tool, but follow up with a database search-replace to fix the URLs permanently. The search-replace is the clean, dependency-free solution.
Cloudflare SSL is configured but I still get redirect loops. Why?
Check Cloudflare’s SSL/TLS encryption mode in your Cloudflare dashboard under SSL/TLS, Overview. If it is set to Flexible, Cloudflare connects to your origin over HTTP. If your origin server has an HTTP-to-HTTPS redirect in .htaccess or through any other mechanism, it redirects Cloudflare’s HTTP request back to HTTPS. Cloudflare follows the redirect but continues connecting to the origin over HTTP, creating a permanent loop. Change Cloudflare’s SSL mode to Full (if your origin has a self-signed certificate) or Full (Strict) (if your origin has a publicly trusted certificate or Cloudflare Origin Certificate). The loop stops immediately.
After fixing SSL, my admin panel, theme styles, and images look broken. What happened?
The visual breakage after enabling HTTPS is almost always mixed content. The browser is loading the page over HTTPS but blocking or warning on resources (CSS, JavaScript, images) that still have http:// URLs. Open Chrome developer tools (F12, Console tab) and look for mixed content errors showing which specific resources are being blocked. Run a WP-CLI search-replace to update the database URLs, clear all caches, and reload. If specific external resources (YouTube embeds, social widgets) still show errors, update their embed codes to use https:// versions.
