Guide · WordPress

Move WordPress from HTTP to HTTPS: Complete SSL Migration Guide

Migrate WordPress to HTTPS safely: install a certificate, update URLs with WP-CLI search-replace, fix mixed content, set 301 redirects and add HSTS.

By SiteDownCheck Editorial · Updated October 5, 2026 · 8 min read

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=guid leaves the guid column alone. GUIDs are identifiers for feed readers and should not change, according to WordPress's own guidance.
  • Run it again for the www variant 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-tables covers 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.php or 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 its https:// 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-requests as 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 Location of the redirect and HSTS.
  • Re-run the mixed content scan after major content edits, since editors can paste http:// links.

Troubleshooting quick list

SymptomLikely cause
Redirect loop after switchingProxy or CDN terminates TLS, WordPress sees HTTP; add the forwarded-proto code or fix the SSL mode
Padlock missing, console warns of insecure resourcesMixed content from hard-coded URLs in theme or builder data
Layout broken, styles missingStylesheet blocked as mixed content or cached builder CSS
Certificate warning on wwwwww not covered by the certificate
Admin login loopssiteurl mismatch or FORCE_SSL_ADMIN without working HTTPS
Images still http:// after search-replaceStored in a table or format not searched, or in theme files

Next steps

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.