Moving a WordPress site from HTTP to HTTPS is mostly a matter of five things done in the right order: get a certificate, tell WordPress its new address, update the URLs stored in the database, fix any remaining insecure resources, and redirect all old HTTP traffic with a permanent redirect. Done carelessly it causes redirect loops, mixed content warnings and lost rankings; done carefully it is invisible to visitors.
Take a full backup of files and database before you start.
Step 1: Get and install a certificate
Most hosts offer free certificates through Let's Encrypt or their own provider, usually in one click in the control panel. On a server you manage with nginx or Apache, Certbot is the standard route:
sudo apt install certbot python3-certbot-nginx # or python3-certbot-apache
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run
Include both the bare domain and www in the certificate, even if only one is canonical, so the redirect from the other works without a certificate warning. Confirm the dry run succeeds, because auto-renewal is what keeps the site online in three months; see how to renew SSL certificates and automate it and Let's Encrypt renewal failures.
Then verify the installation with the SSL Checker: the certificate should match the domain, include the full chain, and not be near expiry. If you see chain or hostname problems, SSL and TLS certificate errors explained covers them.
Before changing anything in WordPress, open https://example.com/ in a browser and make sure it loads without warnings (it may still show mixed content for now).
Step 2: Update the WordPress address
WordPress keeps two options, home and siteurl. Change both to https://:
wp option update home 'https://example.com'
wp option update siteurl 'https://example.com'
Without WP-CLI, edit them in Settings, General. If the settings are greyed out because WP_HOME and WP_SITEURL are defined in wp-config.php, change the constants there. If you get locked out or a loop, see WordPress too many redirects fix.
Also add this to wp-config.php to make admin and login traffic use HTTPS:
define( 'FORCE_SSL_ADMIN', true );
If the site sits behind a proxy, load balancer or CDN that terminates TLS, WordPress needs to know the original request was secure:
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
$_SERVER['HTTPS'] = 'on';
}
Step 3: Replace old URLs in the database with search-replace
Posts, widgets, options and page-builder data often contain absolute http://example.com URLs. Changing the two options above does not touch them, which is the main source of mixed content. Use WP-CLI's search-replace, which correctly handles PHP-serialized data (a plain SQL REPLACE would corrupt serialized values by breaking their length counts):
# 1. Dry run first: shows what would change, writes nothing
wp search-replace 'http://example.com' 'https://example.com' --all-tables --dry-run
# 2. Take a database backup
wp db export before-https.sql
# 3. Run it for real
wp search-replace 'http://example.com' 'https://example.com' --all-tables --skip-columns=guid
Notes on options:
--skip-columns=guidleaves theguidcolumn alone. GUIDs are identifiers for feed readers and should not change, according to WordPress's own guidance.- Run it again for the
wwwvariant if both were used:http://www.example.com. - Also replace protocol-relative forms if you used them, such as
//example.com, though these already work on HTTPS. - On multisite, add
--network. - Page builders store data in post meta, and
--all-tablescovers it. Afterwards, clear their generated CSS cache (for example regenerate CSS in the builder's settings) since stylesheets can embed absolute URLs.
Without WP-CLI, a reputable search-replace tool that supports serialized data is the alternative. Never run a raw SQL UPDATE ... REPLACE() over option values or meta values that may be serialized.
Step 4: Find and fix mixed content
Mixed content means an HTTPS page loads something over HTTP: an image, script, stylesheet, font or iframe. Browsers block active mixed content (scripts, stylesheets, iframes) and may warn about passive content (images), which breaks layouts and removes the padlock.
Scan with the Mixed Content Checker, and in the browser developer tools open the Console, where each blocked or warned resource is listed with its URL. Common sources:
- Hard-coded
http://URLs in theme templates,functions.phpor custom CSS (search the files:grep -rn "http://example.com" wp-content/themes wp-content/plugins). - Images or scripts in widgets and Customizer fields that search-replace missed (text stored in unusual option tables).
- Third-party embeds, fonts and trackers that only have
http://URLs. Replace the URL with itshttps://version, or remove the resource if the provider does not support HTTPS. - CSS
url(http://...)references inside stylesheets. - Content Security Policy: you can add
upgrade-insecure-requestsas a stopgap to make browsers request those resources over HTTPS:
Header always set Content-Security-Policy "upgrade-insecure-requests"
That only works if the resource is actually available over HTTPS, and it is a bandage, not a replacement for fixing the URLs. See the full mixed content fix guide.
Step 5: Redirect HTTP to HTTPS with a 301
Visitors and search engines who still use the old http:// URLs should be permanently redirected, preserving the path and query string. Do this at the web server, since it is faster and more reliable than a plugin.
nginx:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
Apache (.htaccess, above the WordPress block):
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Pick one canonical host (with or without www) and redirect the other to it, in a single hop. Check all four variants (http and https, with and without www) with the Redirect Checker. The target is one 301 to the final HTTPS URL, then a 200. A chain of several hops wastes time and dilutes the signal. For background, see HTTP redirects 301 and 302 explained.
If you use Cloudflare, set the SSL/TLS mode to Full (strict) after installing the origin certificate, not Flexible, otherwise you will get a loop. See Cloudflare setup, DNS and SSL modes.
Step 6: Update everything outside WordPress
- Search Console: add the HTTPS version as a property (a Domain property covers all variants), and submit the HTTPS sitemap. Google treats the move as a site move between URLs and follows the 301s.
- Canonical tags and sitemaps: your SEO plugin should now output HTTPS URLs. Check the source of a page for
<link rel="canonical">. See the robots.txt and sitemap guide. - Analytics, ad platforms, social profiles, email signatures, payment gateway callback URLs and webhooks: update to HTTPS.
- CDN, caching and hotlink rules: purge caches and update any origin or allowlist settings.
- Internal links: search-replace has handled the database, but check manually-entered menu links and image sources.
Step 7: Add HSTS (once everything works)
HTTP Strict Transport Security tells browsers to use HTTPS only for your domain for a stated period, even if someone types http://. It closes the small window where the first request goes over HTTP.
Start with a short period and increase it as confidence grows:
add_header Strict-Transport-Security "max-age=300" always;
Later raise the value to a year (max-age=31536000) and consider includeSubDomains only if every subdomain supports HTTPS. Preloading (preload) is a stronger commitment that is hard to undo; read the HSTS preload guide first. Verify with the HSTS Checker and the Security Headers Checker.
Step 8: Monitor after the move
- Add the HTTPS URL to an uptime monitor with SSL expiry alerts, so a failed renewal reaches you weeks before the date.
- Watch for crawl errors and "redirect error" reports in Search Console for a couple of weeks.
- Check response headers with the HTTP Header Checker, looking for the
Locationof the redirect and HSTS. - Re-run the mixed content scan after major content edits, since editors can paste
http://links.
Troubleshooting quick list
| Symptom | Likely cause |
|---|---|
| Redirect loop after switching | Proxy or CDN terminates TLS, WordPress sees HTTP; add the forwarded-proto code or fix the SSL mode |
| Padlock missing, console warns of insecure resources | Mixed content from hard-coded URLs in theme or builder data |
| Layout broken, styles missing | Stylesheet blocked as mixed content or cached builder CSS |
Certificate warning on www | www not covered by the certificate |
| Admin login loops | siteurl mismatch or FORCE_SSL_ADMIN without working HTTPS |
Images still http:// after search-replace | Stored in a table or format not searched, or in theme files |
Next steps
- Verify the certificate with the SSL Checker.
- Scan for insecure resources with the Mixed Content Checker.
- Confirm one-hop redirects with the Redirect Checker.
- Check HSTS with the HSTS Checker.
- Watch the certificate expiry with the uptime monitor.
FAQ
Will moving to HTTPS hurt my rankings?
Done properly, with 301 redirects, updated canonicals and a sitemap, the effect is usually small and temporary. Problems come from redirect chains, loops, mixed content, or forgetting to redirect some URL variants.
Why not use a plain SQL REPLACE for the URLs?
WordPress stores much data as PHP-serialized strings with length counts. A raw replace changes the length of the text without updating the count, which corrupts the value. WP-CLI's search-replace unserializes, replaces and reserializes correctly.
Do I need a paid certificate?
Not for most sites. Free certificates from Let's Encrypt or your host provide the same encryption. Paid certificates may add warranty or organization validation, which matters for some businesses. See SSL certificate types.
Should I use a plugin to force HTTPS?
A server-level redirect is preferable. A plugin works but adds overhead and can conflict with other redirect rules, producing loops. Pick one place to enforce it.
Is HSTS required?
No, but it is a good final step. Wait until everything works over HTTPS and renewal is automated, and start with a short max-age.
Get notified when this guide updates
Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.
This page is general information written by our editorial team and updated when documentation changes. Servers and providers differ, so test changes safely first. See our editorial policy and disclaimer.