The padlock is the visible part of an HTTPS migration; the risky work hides underneath it. WordPress stores absolute URLs in options and content, plugins serialize configuration, a proxy may terminate TLS before PHP, and years of images can still point at http://. I prefer to treat this as a small site move with a rollback plan, not a settings-panel toggle.

What HTTPS changes—and what it does not

  • TLS encrypts traffic in transit, authenticates the hostname through a trusted certificate chain, and detects tampering on that connection.

  • It does not secure a vulnerable plugin, weak password, compromised administrator, infected origin, unsafe backup, or malicious third-party script.

  • HTTP and HTTPS are different URL schemes; redirects, canonicals, sitemaps, cached HTML, integrations, and search signals must converge on HTTPS.

  • Mixed active content can be blocked by browsers; even passive HTTP resources undermine a clean migration and can expose data.

  • A certificate must cover every served hostname and renew automatically before expiry.

Map the real architecture first

  • Canonical host: apex or www; document every alternate hostname and HTTP variant.

  • TLS termination: origin web server, load balancer, reverse proxy, CDN, or managed host.

  • WordPress form: single site, subdirectory install, subdomain/path multisite, Bedrock/composer deployment, container, or managed platform.

  • Caching layers: page cache, object cache, CDN, browser/service worker, host cache, and proxy cache.

  • Integrations: payments, webhooks, OAuth callbacks, APIs, feeds, email links, analytics, ads, sitemaps, cron, mobile apps, and external asset hosts.

  • Special assets: PDFs, downloads, media offload, CSS-generated URLs, hard-coded theme/plugin strings, structured data, Open Graph, and canonical/hreflang.

Take a restorable baseline

WordPress production root during an approved change windowbash
wp core version
wp plugin list --format=csv > plugins-before-https.csv
wp theme list --format=csv > themes-before-https.csv
wp option get home
wp option get siteurl
wp db export before-https.sql
6.x...
http://www.example.com
http://www.example.com
Success: Exported to before-https.sql.

Risk level: caution. Review the command before running it.

A database dump is necessary but not sufficient

  • Record WordPress, PHP, web-server, plugin, theme, CDN, and certificate/proxy configuration versions.

  • Back up the database, uploads, code/configuration, server/CDN rules, DNS, certificates where appropriate, and external service settings.

  • Database exports can contain personal data, password hashes, API credentials, and reset tokens; store them encrypted and outside the web root.

  • Test restoration into an isolated environment before relying on the backup.

  • Capture representative HTTP status, headers, canonical tags, sitemap URLs, performance, and key user journeys for comparison.

Install and validate the TLS certificate

Trusted external Linux shellbash
openssl s_client -connect www.example.com:443 -servername www.example.com -showcerts </dev/null
curl -sS -I https://www.example.com/
...
Verify return code: 0 (ok)
...
HTTP/2 200
...

Test the hostname users actually request

  • SNI (-servername) asks for the certificate associated with the intended virtual host.

  • Confirm hostname coverage, full chain, issuer, validity dates, signature/key policy, and successful verification from multiple client/network types.

  • Test apex and www separately if both receive traffic, plus required API/media/subdomains.

  • curl confirms an HTTP response but does not exhaust TLS versions, cipher policy, OCSP/revocation behavior, IPv4/IPv6, or regional CDN edges.

  • Automate renewal and expiry monitoring; successful issuance once is not an operational plan.

Make WordPress understand reverse-proxy HTTPS

wp-config.phpphp
/* Trust this header only when a controlled proxy removes client-supplied values. */
if (
    isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) &&
    'https' === strtolower( trim( explode( ',', $_SERVER['HTTP_X_FORWARDED_PROTO'] )[0] ) )
) {
    $_SERVER['HTTPS'] = 'on';
}

The trust boundary is more important than the snippet

  • Use this only when the load balancer/reverse proxy owns and sanitizes X-Forwarded-Proto; otherwise a client can spoof it.

  • Some platforms provide a documented native HTTPS environment variable or WordPress integration—prefer the platform’s supported configuration.

  • A comma-separated forwarding chain has topology-specific semantics; configure the proxy and application together rather than copying parsing blindly.

  • Correct scheme detection prevents redirect loops, insecure cookies, and HTTP URLs generated behind TLS termination.

  • Test direct-origin access and ensure attackers cannot bypass the trusted proxy.

Preview WordPress database URL changes

WordPress root or staging clonebash
wp search-replace 'http://www.example.com' 'https://www.example.com' \
  --all-tables-with-prefix \
  --skip-columns=guid \
  --precise \
  --dry-run \
  --report-changed-only
Success: 247 replacements to be made.

Use a serialization-aware replacement

  • WP-CLI understands serialized WordPress values; raw SQL/string replacement can corrupt serialized lengths and data.

  • Use the exact old canonical origin, including host and port if applicable, to avoid altering unrelated external URLs.

  • --all-tables-with-prefix includes custom/plugin tables sharing the current prefix; inventory nonstandard or network tables separately.

  • WordPress migration guidance commonly skips the posts guid column because GUIDs identify feed items and are not ordinary display URLs.

  • --precise uses PHP processing for compatibility at a performance cost; review installed WP-CLI behavior.

  • A dry run reports intent but does not lock the database; control writers or use a maintenance/snapshot strategy.

Update home and siteurl deliberately

WordPress production rootbash
wp option update home 'https://www.example.com'
wp option update siteurl 'https://www.example.com'
wp option get home
wp option get siteurl
Success: Updated 'home' option.
Success: Updated 'siteurl' option.
https://www.example.com
https://www.example.com

Risk level: caution. Review the command before running it.

These two options answer different WordPress questions

  • home is the visitor-facing site address; siteurl locates WordPress core files. They can differ for certain directory layouts.

  • If WP_HOME or WP_SITEURL constants are defined, database option changes may appear ineffective; audit configuration first.

  • For multisite, network/site URL updates require network-aware commands and a tested migration plan.

  • Changing the wrong host/path can lock out wp-admin; keep WP-CLI/database rollback access.

  • Purge WordPress, object, page, proxy, and CDN caches only through the platform’s supported controls after changes.

Run the reviewed search-replace

WordPress root after backup and dry-run approvalbash
wp search-replace 'http://www.example.com' 'https://www.example.com' \
  --all-tables-with-prefix \
  --skip-columns=guid \
  --precise \
  --report-changed-only
... tables and replacement counts ...
Success: Made 247 replacements.

Risk level: caution. Review the command before running it.

Replacement count is evidence, not proof

  • Save the reviewed dry-run and execution reports with the change record.

  • Unexpectedly huge or zero counts deserve investigation before continuing.

  • The command does not inspect files, compiled CSS, CDN databases, external services, browser caches, or tables outside its selected scope.

  • Search afterward for old URLs in database, source/build artifacts, generated caches, and public responses.

  • Validate forms, media, widgets, menus, blocks, page builders, serialized plugin settings, APIs, and background jobs.

Fix mixed content at the source

WordPress root and public sitebash
wp search-replace 'http://www.example.com' 'https://www.example.com' --all-tables-with-prefix --skip-columns=guid --dry-run
curl -sSL https://www.example.com/ | grep -Eo 'http://[^"< ]+' | sort -u
... remaining database candidates ...
http://legacy-assets.example.net/image.jpg

Browser warnings can come from many layers

  • Inspect HTML attributes, srcset, inline styles/scripts, CSS url(), JavaScript requests, iframes, fonts, manifests, feeds, JSON, and generated metadata.

  • Use browser DevTools Console/Network and a crawler across representative templates, not only homepage text matching.

  • Move third-party resources to a verified HTTPS endpoint or self-host them with licensing, privacy, cache, and update implications understood.

  • Do not blindly rewrite external http:// URLs: some endpoints do not support HTTPS or refer to intentional identifiers/content.

  • CSP upgrade-insecure-requests can be defense in depth, but it can hide broken origins and is not a database/content migration.

Add one-hop permanent redirects

https-redirect-vhost.confapache
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L,NE]

Apache should preserve the path and query string

  • Scope the rule to known HTTP virtual hosts and send every old URL to its direct HTTPS equivalent.

  • The query string is preserved by default when the substitution has none; NE avoids re-escaping special characters in the redirect target.

  • Behind a proxy, %{HTTPS} may remain off and loop; enforce the redirect at the TLS-aware edge or use a trusted proxy signal.

  • Test syntax and configuration in staging, then inspect representative redirects before broad rollout.

  • Use a permanent status only after the destination is proven; 308 can preserve request methods more strictly, while common GET/HEAD migrations often use 301.

http-vhost.confnginx
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
 
    return 301 https://www.example.com$request_uri;
}

Nginx can redirect before PHP runs

  • A dedicated port-80 server avoids per-request WordPress/plugin redirect logic.

  • $request_uri retains the original path and query string.

  • Choose the canonical host explicitly so http://example.com/x reaches https://www.example.com/x in one hop.

  • Retain HTTP service for redirects and ACME validation as required by the certificate strategy; do not simply drop port 80.

  • Validate configuration, reload safely, and test both IPv4 and IPv6 endpoints.

Test the redirect matrix

External shellbash
for url in \
  http://example.com/sample/?a=1 \
  http://www.example.com/sample/?a=1 \
  https://example.com/sample/?a=1 \
  https://www.example.com/sample/?a=1
do
  curl -sS -o /dev/null -w '%{http_code} %{url_effective} %{redirect_url}\n' "$url"
done
301 http://example.com/sample/?a=1 https://www.example.com/sample/?a=1
301 http://www.example.com/sample/?a=1 https://www.example.com/sample/?a=1
301 https://example.com/sample/?a=1 https://www.example.com/sample/?a=1
200 https://www.example.com/sample/?a=1

Every legacy variant should converge once

  • Check apex/www, HTTP/HTTPS, meaningful paths, query strings, encoded characters, files, feeds, sitemaps, API routes, and old high-traffic URLs.

  • Avoid chains such as HTTP apex → HTTPS apex → HTTPS www.

  • Do not redirect missing/deleted pages indiscriminately to the homepage; preserve valid mappings or return 404/410.

  • Test POST/webhook/API behavior before choosing redirect status and placement.

  • Automate the expected matrix so future CDN/server changes cannot silently add loops or chains.

Update SEO and discovery signals

  • Every indexable HTTPS page emits a self-consistent HTTPS canonical, unless intentionally canonicalized elsewhere.

  • XML sitemaps contain only final canonical HTTPS URLs and return clean HTTPS responses.

  • Robots.txt, hreflang, structured data, Open Graph/Twitter metadata, feeds, pagination, manifests, and internal links use HTTPS.

  • Verify the Domain property and relevant HTTPS URL-prefix property in Search Console; HTTP→HTTPS does not use Change of Address.

  • Submit the HTTPS sitemap and monitor Page Indexing, URL Inspection, crawl stats, performance, errors, and security/manual-action reports.

  • Update analytics, ads, merchant feeds, social profiles, email templates, QR codes, and important external links where practical.

Cookies, admin, APIs, and integrations

  • Confirm authentication/session cookies are Secure where appropriate and proxy scheme detection is correct.

  • Test login/logout, password reset, comments, search, forms, checkout, account pages, uploads, REST API, XML-RPC if used, cron, and wp-admin.

  • Update OAuth redirect URIs, webhook endpoints, payment callbacks, CORS allowlists, CSP, API clients, mobile apps, and allowlists.

  • Some partners validate exact callback URLs or certificates; coordinate before the cutover.

  • Check outbound emails and generated documents for stale HTTP links.

  • Avoid forcing admin-only SSL as a substitute for whole-site HTTPS; public forms/content also deserve protected transport.

HSTS comes last

https-response-header.txttext
Strict-Transport-Security: max-age=300

Start with a short policy and observe

  • HSTS tells supporting browsers to use HTTPS for future requests to the host until max-age expires.

  • Enable it only after HTTPS, renewal, redirects, subresources, and rollback have been stable.

  • Begin with a short duration, monitor, then increase deliberately.

  • Do not add includeSubDomains until every present and future subdomain can sustain HTTPS.

  • Do not request browser preload until you understand its long-lived requirements and removal delay; preload is not a first-day optimization.

Do not forget caches and service workers

  • Purge server/page/object/CDN caches in the correct order after origin correctness is proven.

  • Invalidate cached redirects and HTML that embed HTTP canonicals/assets.

  • Review service-worker scope, cache names, precache manifests, and update behavior; an old worker can keep serving stale HTTP references.

  • Set CDN origin protocol and host correctly, avoiding flexible/partial TLS modes that leave origin traffic or scheme detection wrong.

  • Monitor cache hit ratios and origin load because migrations and crawler recrawling can temporarily increase traffic.

Verification after cutover

  • TLS chain/hostname/expiry work from representative clients, networks, IPv4, and IPv6.

  • Every HTTP/alternate-host URL maps to the final HTTPS equivalent in one permanent redirect.

  • No redirect loops, chains, certificate warnings, mixed content, CSP errors, or blocked active resources appear.

  • WordPress home/siteurl, generated URLs, media, canonical, hreflang, structured/social metadata, feeds, robots, and sitemap are HTTPS.

  • Critical anonymous and authenticated journeys pass on desktop/mobile and supported browsers.

  • Search Console sees live HTTPS URLs, the new sitemap is accepted, and logs show Googlebot/user traffic without unusual errors.

  • Certificate renewal, uptime, redirect, mixed-content, application error, and search monitoring are active.

Troubleshooting failures

  • Too many redirects: WordPress sees HTTP behind a TLS proxy, or edge/server/plugin redirects disagree; fix trusted scheme detection and centralize canonicalization.

  • wp-admin login loop: inspect proxy HTTPS detection, cookie security/domain/path, home/siteurl, cache, and host redirects.

  • Images/styles blocked: find database, template, CSS, builder, CDN, or third-party HTTP URLs and repair the origin.

  • Certificate valid on www only: issue/configure coverage for every traffic-receiving hostname before redirecting it.

  • Old HTTP URLs in search: verify redirects/canonicals/sitemap/internal links, inspect URLs in Search Console, and allow recrawl time.

  • WP-CLI changes zero rows: constants, exact old host, custom tables, multisite, prefixes, or prior partial migration may explain it—inspect rather than widening replacement blindly.

  • Site breaks after search-replace: restore, identify raw SQL/encoding/serialization/plugin assumptions, and repeat in staging with WP-CLI or a supported migration tool.

  • Webhook/API fails: partner may not follow 301 or may sign the original URL; register and test the HTTPS endpoint explicitly.

Rollback without creating split-brain URLs

  • Keep the old configuration and database/files backup immediately restorable.

  • Define which failures justify rollback and who can approve it.

  • If HTTPS itself is unavailable, rollback certificate/proxy/application changes through the prepared procedure; do not rely on clients ignoring TLS errors.

  • Be cautious after HSTS: browsers may refuse HTTP fallback even if you remove redirects.

  • Restore database/config/cache/CDN states coherently, then re-run smoke tests and communicate impact.

  • Preserve logs and timeline for root-cause analysis before attempting a corrected migration.

Primary references