Back to tutorials
Tutorial

VPS SSL Certificate Migration Tutorial (2026): Move HTTPS to a New Server Without Downtime, Mismatched Chains, or Renew Failures

VPS SSL certificate migration tutorial for clean HTTPS cutovers: export, install, validate chains, and avoid renewal failures in 2026.

By Anurag Singh
Updated on Sep 28, 2026
Category: Tutorial
Share article
VPS SSL Certificate Migration Tutorial (2026): Move HTTPS to a New Server Without Downtime, Mismatched Chains, or Renew Failures

Most “SSL migration” failures aren’t about the certificate itself. They happen during cutover. The wrong chain gets installed. The private key never makes it across. DNS points somewhere unexpected. Renewals keep running on the old box. This VPS SSL certificate migration tutorial shows a clean way to move HTTPS to a new VPS, with verification steps you can run before you touch DNS.

The workflow applies whether you’re moving WordPress, a custom PHP app, or a multi-site hosting VPS. You’ll see both cPanel/WHM and “plain Linux” paths. Real migrations rarely stay inside one tool.

What you’ll migrate (and what you should not)

Before you run commands, be clear on what HTTPS on a VPS actually consists of:

  • Certificate (public cert): safe to move.
  • Private key: must match the certificate; treat it like credentials and lock down permissions.
  • Intermediate chain: the piece most often missing after a move. Missing intermediates cause “incomplete chain” warnings or failures in picky clients.
  • Renewal method: Certbot, cPanel AutoSSL, acme.sh, Plesk, etc. Migrating HTTPS without migrating renewal is how sites break a month later.
  • HTTP→HTTPS redirects and application URLs: easy to copy, easy to get wrong, and a common cause of loops and mixed content.

What you generally shouldn’t migrate: old Let’s Encrypt account state across very different setups. Also avoid opaque control-panel SSL stores unless you have a specific reason.

In 2026, it’s usually safer to re-issue a new Let’s Encrypt cert on the new server after DNS cutover. The main exceptions are EV/OV certs, pinned certificates, or compliance-driven certs that can’t be reissued quickly.

Prerequisites checklist (do this first)

  • New VPS is provisioned and patched. If it’s fresh Ubuntu/Debian, follow a hardening baseline first; see this Ubuntu VPS hardening tutorial.
  • Web server is installed and serving the site over HTTP (temporary is fine) so you can validate routing and vhosts.
  • You know where DNS is hosted and can lower TTL ahead of time. If you want a clean rollback plan, use this DNS cutover tutorial.
  • You can access the old server as root/admin to export keys (or you have the CA bundle from your certificate vendor).
  • You’ve confirmed the new server IP and set rDNS/PTR if mail lives on the same box (not required for web-only, but common in hosting).

If you need a VPS that can handle the “noisy” part of a migration and then scale down later, start on a HostMyCode VPS. Predictable CPU and I/O help when you’re copying data, warming caches, and validating under load.

Step 1: Identify how SSL is managed on the old server

Your goal is simple: find the authoritative private key and the process that renews it.

On a plain Linux VPS

Typical places to look:

  • Nginx: /etc/nginx/sites-available/ and certificate paths often under /etc/letsencrypt/live/
  • Apache: vhosts in /etc/apache2/sites-available/ with SSLCertificateFile paths
  • Certbot: systemctl list-timers | grep certbot or crontab -l
sudo nginx -T 2>/dev/null | grep -E "ssl_certificate|ssl_certificate_key" | head
sudo apachectl -S 2>/dev/null | head
sudo certbot certificates 2>/dev/null

On cPanel/WHM

cPanel typically uses AutoSSL (Let’s Encrypt or Sectigo, depending on licensing and configuration). In WHM, check:

  • WHM → SSL/TLS → Manage AutoSSL
  • WHM → SSL/TLS → Install an SSL Certificate on a Domain (to view cert/key/CA bundle)

Watch for the common exception. One domain may use a purchased OV/EV cert installed manually. Everything else may use AutoSSL.

Step 2: Export the certificate and private key safely

If you can re-issue the certificate on the new VPS (common with Let’s Encrypt), that’s usually the cleanest path. Still, exporting the existing cert is sometimes the right move:

  • You have an OV/EV cert you can’t re-issue instantly.
  • You’re keeping the same cert for compliance/pinning.
  • You’re migrating behind a load balancer or CDN and want identical origin certs.

Option A (recommended for most Let’s Encrypt sites): plan to re-issue on the new VPS

Don’t copy /etc/letsencrypt and hope it behaves. Migrate the site first. Then issue a fresh cert on the new server once DNS points to it.

This avoids renewal-state mismatches, stale webroot paths, and broken deploy hooks.

If you’re on Nginx and hosting multiple sites, clean up server blocks before you issue anything; see this Nginx server blocks tutorial.

Option B: export an existing certificate + key (plain Linux)

First, prove the certificate matches the private key. On the old server:

# Replace paths as needed
CERT=/etc/letsencrypt/live/example.com/fullchain.pem
KEY=/etc/letsencrypt/live/example.com/privkey.pem

openssl x509 -noout -modulus -in "$CERT" | openssl md5
openssl rsa  -noout -modulus -in "$KEY"  | openssl md5

The MD5 outputs must match. If they don’t, stop.

Your web server is likely pointing at a different key than you think.

Copy the files into a root-only staging directory. Then lock down permissions:

sudo install -d -m 700 /root/ssl-migrate
sudo cp -a /etc/letsencrypt/live/example.com/fullchain.pem /root/ssl-migrate/
sudo cp -a /etc/letsencrypt/live/example.com/privkey.pem   /root/ssl-migrate/
sudo chmod 600 /root/ssl-migrate/privkey.pem

Transfer to the new server over SSH. Use a restricted destination:

scp -p /root/ssl-migrate/fullchain.pem /root/ssl-migrate/privkey.pem root@NEW_SERVER_IP:/root/ssl-migrate/

Option C: export from cPanel/WHM

In WHM, open Install an SSL Certificate on a Domain. Copy:

  • Certificate (CRT)
  • Private Key (KEY)
  • Certificate Authority Bundle (CABUNDLE) (if provided)

Store them in a password manager or a root-only file on your admin workstation. Don’t paste private keys into chat tools or ticket systems.

Step 3: Install the cert on the new VPS (Nginx and Apache examples)

On the new server, place the files where your web server expects them. For a typical Nginx/Apache setup without a control panel, a practical convention is:

  • /etc/ssl/private/ for keys (root-only)
  • /etc/ssl/certs/ for certificates
sudo install -d -m 700 /etc/ssl/private
sudo install -d -m 755 /etc/ssl/certs

sudo cp /root/ssl-migrate/privkey.pem /etc/ssl/private/example.com.key
sudo cp /root/ssl-migrate/fullchain.pem /etc/ssl/certs/example.com.fullchain.pem

sudo chmod 600 /etc/ssl/private/example.com.key
sudo chmod 644 /etc/ssl/certs/example.com.fullchain.pem

Nginx server block snippet

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate     /etc/ssl/certs/example.com.fullchain.pem;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    # Good defaults for 2026 (keep your distro's recommended ciphers where possible)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;

    root /var/www/example.com/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
}

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}
sudo nginx -t && sudo systemctl reload nginx

Apache vhost snippet

<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/example.com.fullchain.pem
    SSLCertificateKeyFile /etc/ssl/private/example.com.key

    Protocols h2 http/1.1

    DocumentRoot /var/www/example.com/public

    <Directory /var/www/example.com/public>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    Redirect permanent / https://example.com/
</VirtualHost>
sudo a2enmod ssl http2 headers rewrite
sudo apachectl configtest && sudo systemctl reload apache2

Step 4: Verify the chain and SNI before you cut DNS

Don’t use your visitors as monitoring. Test from your workstation instead. Force SNI and force resolution to the new IP.

Replace 203.0.113.10 with your new server IP.

# Check what the new server presents on 443
openssl s_client -connect 203.0.113.10:443 -servername example.com -showcerts </dev/null | openssl x509 -noout -subject -issuer -dates

Then run a full handshake test. Watch for chain problems:

curl -Iv --resolve example.com:443:203.0.113.10 https://example.com/
  • If you see SSL certificate verify ok. in verbose output, the chain is probably fine.
  • If you see unable to get local issuer certificate, you’re missing intermediate(s). For most Let’s Encrypt installs, you want fullchain.pem (not cert.pem).

On cPanel moves, chain issues can be sneaky. Browsers may look fine, but API clients fail. That often points to an incomplete bundle.

If you run into renewal errors, keep this renewal troubleshooting guide close.

Step 5: Avoid the most common migration trap—renewals still happening on the old server

This failure pattern wastes the most time. The site moves cleanly and everything looks good. Then, 30–60 days later, HTTPS expires because the new server never renewed.

The old server, meanwhile, keeps renewing a certificate that no longer matters.

If you’re using Certbot

On the new server, confirm the timer exists and is active:

systemctl list-timers | grep -E "certbot|acme" || true
sudo systemctl status certbot.timer 2>/dev/null || true

Run a dry-run renewal (safe):

sudo certbot renew --dry-run

If you’re on cPanel AutoSSL

In WHM, confirm AutoSSL is enabled and that the account/domain is included. After DNS cutover, it’s useful to force a run for a single user:

/usr/local/cpanel/bin/autossl_check --user=username --verbose

After cutover: disable renewals on the old server

Once traffic is stable on the new VPS and rollback is off the table, stop renewal on the old box. That prevents confusion later.

  • Disable certbot.timer on the old server, or remove its cron.
  • In cPanel, you can leave AutoSSL enabled. Still, consider suspending the account or disabling vhosts once decommission starts.

Step 6: Cut DNS with HTTPS-safe validation

Lower TTL ahead of time if you can. During cutover, prove you’re hitting the new server.

Don’t trust a single cached resolver, a stale CDN edge, or the wrong vhost.

  1. Set DNS A/AAAA records to the new server.
  2. Verify from multiple networks (a mobile hotspot is often enough).
  3. Check that www and the apex domain both present the correct certificate.

These two quick checks catch most “wrong server” mistakes:

# Show the IP your resolver sees
dig +short example.com A

# Confirm the certificate subject on the live domain
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -subject -issuer

If DNS looks correct but you hit redirect loops, don’t keep reinstalling certificates. Fix the redirect logic.

Use this HTTPS redirect troubleshooting tutorial to isolate whether the loop comes from your app, proxy headers, or incorrect scheme detection.

Step 7: WordPress-specific SSL sanity checks after migration

WordPress moves often “work” while still hiding a few HTTPS problems. Catch them early.

Checklist

  • Site URL: ensure both “WordPress Address” and “Site Address” are https://.
  • Mixed content: scan your homepage for http:// asset URLs in HTML/CSS.
  • Real IP / HTTPS detection: if you’re behind a CDN or proxy, set correct headers so WordPress sees HTTPS.
  • Admin login: confirm /wp-admin loads without redirects bouncing between HTTP and HTTPS.

If updates start failing after the move due to permissions or a stuck maintenance state, fix it quickly with this WP-CLI troubleshooting guide.

Step 8: cPanel/WHM migration notes (AutoSSL, SNI, and multi-domain reality)

On hosting VPSes, you’re rarely moving one domain. You’re usually moving dozens (or hundreds).

Each domain can have its own vhost and redirects. Some will also have mail routing. A few cPanel-specific checks keep SSL predictable:

  • Use AutoSSL wherever possible on the new server. It reduces manual CRT/KEY handling and keeps renewals consistent.
  • Confirm hostname SSL in WHM. A missing or incorrect hostname certificate can break service UIs and API tooling.
  • Check SNI collisions: if you had custom vhost includes or non-standard Apache configs, verify each domain lands on the intended vhost.
  • Don’t forget mail-related DNS if mail stays on the box (SPF/DKIM/DMARC/PTR). Web SSL moves often surface mail reputation issues at the same time.

If you need the mail-side checklist, reference this email deliverability setup guide after cutover.

Step 9: Post-migration monitoring for SSL and renewals

For the first week after cutover, keep it boring and repetitive. Check expiry, skim renewal logs, and watch error rates.

Quick diagnostics

# Expiry date (from any machine)
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate

# Nginx/Apache errors (new server)
sudo tail -n 50 /var/log/nginx/error.log 2>/dev/null || true
sudo tail -n 50 /var/log/apache2/error.log 2>/dev/null || true

Add an external uptime/SSL expiry check as well. If you’d rather self-host monitoring, this Uptime Kuma monitoring tutorial fits well for VPS owners.

Common SSL migration failures (and the fast fix)

  • “NET::ERR_CERT_COMMON_NAME_INVALID”: you installed a cert for the wrong hostname. Re-issue or reinstall the correct cert for that FQDN.
  • “Incomplete chain”: you used cert.pem instead of fullchain.pem, or forgot the CA bundle for an OV/EV cert.
  • Cert works for apex but not www: missing SAN for www, or a separate vhost without SSL configured.
  • Renew fails after migration: DNS still points elsewhere, firewall blocks port 80 for HTTP-01, or the renew tool was never installed/enabled on the new VPS.
  • Redirect loop after enabling HTTPS: app thinks it’s on HTTP due to proxy headers or mis-set X-Forwarded-Proto. Fix the scheme detection, not the certificate.

Summary: a VPS SSL certificate migration tutorial flow you can reuse

  • Decide: re-issue on the new server (preferred) or export the existing CRT/KEY.
  • Install with correct permissions and always serve the full chain.
  • Validate with curl --resolve and openssl s_client before DNS changes.
  • After cutover, confirm renewals run on the new server—and stop them on the old one.

If you migrate customer sites regularly (or you just want fewer moving parts), a managed VPS hosting plan from HostMyCode can cover patching, monitoring, and the classic “why did SSL stop renewing?” surprises. If you prefer hands-on control, start with a HostMyCode VPS and scale resources during the cutover window.

If you’re planning a server move in 2026, rehearse this SSL migration workflow on a staging hostname first. Then cut DNS with a rollback plan in hand. HostMyCode can support a clean move on a HostMyCode VPS, or take on the operational work with managed VPS hosting.

FAQ

Should I copy /etc/letsencrypt from the old server to the new server?

Usually no. It can work, but it often drags along renewal hooks, webroot paths, and account state. Those details may not match the new layout.

Re-issuing on the new VPS is cleaner unless you have a strong reason to keep the exact certificate.

How do I test the new VPS certificate before DNS cutover?

Use SNI with a forced resolve: curl -Iv --resolve example.com:443:NEW_IP https://example.com/. That tests the exact hostname against the new server, without waiting for DNS propagation.

What file should I configure in Nginx/Apache: cert.pem or fullchain.pem?

Use fullchain.pem for Let’s Encrypt in almost all cases. It includes the intermediate chain that many clients require.

My site works, but renewal fails on the new server. What’s the first thing to check?

Start with the validation method. HTTP-01 requires port 80 reachable and the correct webroot/vhost. DNS-01 requires working API credentials and control of the correct zone.

Then run certbot renew --dry-run and read the error output carefully.

Do I need to migrate SSL for mail too?

If your VPS also runs SMTP/IMAP, yes—mail services use their own TLS certificates and hostname expectations. Plan web and mail together, and verify SPF/DKIM/DMARC and PTR after the move.