Use a server-level permanent (301) redirect to send every HTTP request to HTTPS, then confirm the change actually works. The cleanest paths are an Apache VirtualHost or .htaccess rule, an NGINX server block, a hosting panel toggle, or WordPress configuration, depending on what you control. After the redirect is live, test it, hunt down mixed content, and roll out HSTS carefully once everything loads securely.
TL;DR:
- Use a server-level 301 redirect on Apache or NGINX to ensure all HTTP requests permanently redirect to HTTPS, avoiding mixed content issues.
- When creating redirects, exclude the ACME challenge path to prevent SSL certificate renewal failures, especially with Let's Encrypt.
- For reverse proxy setups, check the
X-Forwarded-Protoheader to prevent redirect loops caused by misconfigured protocol detection.- On shared hosting, enable a "Force HTTPS" toggle in the control panel, but prefer server configuration for better performance and coverage.
- After redirect setup, verify with curl and browser tools that all requests properly redirect to HTTPS and address mixed content before enabling HSTS slowly.
Table of Contents
- Apache: VirtualHost and .htaccess examples and why 301 is preferred
- NGINX: minimal server block and proxy-aware redirects
- cPanel and hosting control panel quick options
- WordPress checklist: update URLs, prefer server redirects, and fix mixed content
- Testing and safe HSTS rollout: how to verify redirects and when to enable HSTS
- Troubleshooting: loops, port mapping, ACME failures, and reverse proxy gotchas
- Author perspective: why we apply server-level redirects and staged HSTS
- inSave Hosting: free SSL, easy redirects, and managed help
- FAQ
- Sources
Apache: VirtualHost and .htaccess examples and why 301 is preferred
If you manage your own Apache configuration, the cleanest method is a dedicated HTTP VirtualHost that does nothing but redirect. Inside the port 80 block, a single Redirect permanent line sends every request to the HTTPS version of the same path:
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
This approach is simpler and more reliable than mod_rewrite when you have full access to the server configuration, according to Apache's own documentation.
On shared hosting, where you typically cannot edit the main server config, an .htaccess rule in your site's root directory does the same job:
- Turn on the rewrite engine with
RewriteEngine On. - Add a condition that checks for non-HTTPS requests:
RewriteCond %{HTTPS} !=on. - Apply the redirect:
RewriteRule ^(.*)$ https://%{http_host}%{request_uri} [R=301,L].
That three-line block, run in sequence, catches every HTTP request and forwards it permanently to the matching HTTPS URL. A step-by-step Apache guide from Linuxize walks through the same pattern and notes that a 301 redirect preserves the link equity search engines have already assigned to your pages, which matters if your site has any inbound links or search rankings worth protecting.
Why 301, specifically? A 301 tells browsers and search engines that the move is permanent, so bookmarks update and search indexes transfer ranking signals to the new HTTPS URLs. A 308 behaves almost identically but, unlike 301, guarantees that the request method and body are preserved on the next hop, which matters for POST requests hitting an API endpoint. For a standard website redirect, 301 is the long-established, universally supported choice; reserve 308 for cases where you are redirecting form submissions or API calls that must not silently become GET requests.
Pro Tip: If you're issuing certificates with certbot's webroot plugin, don't let your redirect rule catch the ACME challenge path. Add an exception for /.well-known/acme-challenge/ before the redirect line, or the certificate authority's validation requests will bounce off your HTTPS redirect and fail.
That caution is not theoretical. Community troubleshooting threads describe exactly this failure mode: Let's Encrypt's HTTP-01 challenge starts on port 80 and can follow a redirect to HTTPS, but the initial connection has to reach port 80 first. When a blanket redirect or a firewall rule blocks that path entirely, renewal fails silently until someone notices the certificate is about to expire.
One more detail worth confirming before you move on: check that your .htaccess rule sits above any WordPress-generated rewrite block, since Apache processes rules top to bottom and a misplaced redirect can get skipped entirely.
NGINX: minimal server block and proxy-aware redirects
NGINX handles this with a dedicated server block listening on port 80. The entire redirect logic fits in one line:
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
This pattern, recommended in Linuxize's NGINX redirect guide, preserves the full path and query string while sending a permanent redirect status. For most websites, return 301 is the right call.
- Use
return 308instead of 301 for API endpoints where it is necessary to preserve the request method and body upon redirect. - Set
server_name _;as a catch-alldefault_serverblock so requests to unrecognized hostnames still get a sane redirect instead of a connection error. - If you run multiple sites, give each its own server block rather than relying on one generic redirect for every domain.
Pro Tip: During local development or staging, swap return 301 for return 302 temporarily. Browsers cache 301 redirects aggressively, so a misconfigured permanent redirect can stick around in your browser long after you've fixed the underlying rule, making debugging confusing.
Sites running behind a reverse proxy, load balancer, or TLS-terminating CDN need an extra layer of care. The proxy often handles the actual TLS termination and forwards plain HTTP to your origin server internally, which means your origin has no direct way to know the original request arrived over HTTPS. Community discussions on NGINX configuration point to the same root cause behind most redirect loops in these setups: the origin redirects to HTTPS, the proxy terminates TLS and forwards HTTP again, and the cycle repeats. The fix is to trust and read the X-Forwarded-Proto header from your proxy, then base your redirect logic on that header's value instead of blindly redirecting every request your origin sees.

Port-mapped development environments cause a related headache: $host can drop a non-standard port, producing a redirect to the wrong address. Applications with their own URL generation, such as Laravel's URL::forceScheme, often handle this better by deriving the external URL from a trusted header or an explicit APP_URL setting rather than hard-coding a port into server-side variables.
cPanel and hosting control panel quick options
If you're on shared hosting and don't have direct access to Apache or NGINX configuration files, your hosting panel usually offers a GUI shortcut. Most cPanel-based accounts include a "Force HTTPS Redirect" toggle under the domain or SSL/TLS section, and page rule or redirect tools exist under similarly named menus in other panels.
- Look for a "Force HTTPS" or "Redirect" option in your domain management or SSL/TLS settings.
- Pair it with AutoSSL or a similar free certificate issuance tool so the redirect has a valid certificate to land on.
- Check for a "Page Rules" or "Redirects" section if your panel doesn't expose a dedicated HTTPS toggle.
Free SSL issuance through AutoSSL or Let's Encrypt integration typically runs automatically once a domain is verified, and pairing it with the panel's redirect toggle gets you from plain HTTP to enforced HTTPS in a couple of clicks.
That said, a server-config redirect (Apache or NGINX directly) still tends to outperform a panel-level or plugin-based rule: it executes earlier in the request cycle, before PHP or application code loads, and it automatically covers static assets like images and stylesheets that a plugin-based redirect might miss.
WordPress checklist: update URLs, prefer server redirects, and fix mixed content
WordPress stores its own site URLs in the database, so a server-level redirect alone won't stop the dashboard or theme from generating HTTP links internally. Work through this checklist after your redirect is in place:
- Go to Settings → General and change both the WordPress Address (URL) and Site Address (URL) fields to the
https://version; if the dashboard is unreachable, defineWP_HOMEandWP_SITEURLdirectly inwp-config.phpinstead. - Keep the actual redirect at the server level (Apache or NGINX) rather than relying on a plugin, since a plugin redirect only runs after WordPress and PHP have already loaded.
- Run a search-and-replace for hardcoded
http://links left in post content, widgets, or theme options, using WP-CLI'ssearch-replacecommand or a well-reviewed plugin built for the task. - Crawl the site with a link checker to confirm nothing still points to the old protocol.
- Clear any object cache, page cache, and CDN cache so visitors don't keep receiving cached HTTP references.
A redirect plugin isn't useless, it can serve as a quick stopgap while you sort out server access or troubleshoot an edge case, but it shouldn't be the permanent solution once you have config-level access.
Pro Tip: Run your homepage through browser devtools after the search-and-replace step. Any resource still loading over http:// will show up as a blocked or flagged request in the console, which is faster than scanning raw HTML for stray links.
For a deeper walkthrough of locating and fixing leftover insecure resources, our developer checklist for mixed-content fixes covers WP-CLI commands and automated scanning tools in more detail.
Testing and safe HSTS rollout: how to verify redirects and when to enable HSTS
Before trusting any redirect, check it directly instead of assuming the browser's address bar tells the full story.
- Run
curl -I http://example.comand confirm the response showsHTTP/1.1 301 Moved Permanentlywith aLocation:header pointing to the HTTPS URL. - Open browser devtools, switch to the Network tab, reload with cache disabled, and verify the initial request returns a 301 before the HTTPS version loads.
- Run the domain through an online redirect checker to confirm the behavior holds from outside your own browser session, which may have cached results.
Mixed content is the next thing to chase down. Open the browser console on every major page template and look for warnings about insecure resources; MDN's guidance on mixed content splits these into "upgradable" content, which browsers silently load over HTTPS anyway, and "blockable" content, which simply fails to load. Replacing hardcoded http:// references with https:// or protocol-relative paths is the most dependable fix, since you can't count on every browser to auto-upgrade a blockable resource.
Once the site loads cleanly over HTTPS with no mixed-content warnings, HSTS is worth adding, but only in stages. Ssl recommends starting with a short max-age value and leaving out includeSubDomains at first, since HSTS instructs browsers to refuse any HTTP connection to your domain for the duration of that max-age, with no way to override it if something was missed. Only after confirming every subdomain and resource is HTTPS-ready should you raise the max-age and consider submitting to an HSTS preload list.
Certificate renewal deserves a final check: Let's Encrypt's HTTP-01 validation method begins on port 80 and can follow a redirect to HTTPS, so confirm your renewal path still completes successfully after any redirect changes rather than assuming it will.
Troubleshooting: loops, port mapping, ACME failures, and reverse proxy gotchas
Most HTTP-to-HTTPS problems fall into a handful of repeatable patterns.
- Redirect loops: these usually come from a proxy and origin server each redirecting the other's request. Check whether both layers are issuing a redirect, and confirm your origin reads
X-Forwarded-Protorather than redirecting every request it receives regardless of the original protocol. - Dropped or wrong ports:
$hostin NGINX, or similar variables in other servers, can omit a non-standard port, sending visitors to a URL that doesn't match their actual connection. Switch to a temporary 302 while debugging so your browser doesn't cache a broken 301. - ACME challenge failures: if Let's Encrypt renewal fails, confirm
/.well-known/acme-challenge/is reachable over plain HTTP on port 80, or switch to a DNS-01 or TLS-ALPN-01 challenge type if port 80 access is restricted. - Diagnostics worth running first:
curl -vagainst the affected URL,nginx -torapachectl configtestto catch syntax errors before reloading, and a scan of your access and error logs for repeated redirect entries pointing at the same URL.
Working through these in order, starting with the logs and a verbose curl request, resolves the overwhelming majority of redirect issues without guesswork.
Author perspective: why we apply server-level redirects and staged HSTS
We lean on server-level redirects and copy-ready configuration snippets because they fail less often than plugin-based alternatives, and when they do fail, the cause is usually visible in a log file within minutes. We bundle free SSL and WordPress security headers into our hosting setup for the same reason: fewer manual steps means fewer places for a redirect rule to go wrong during a migration.
Our one standing caution is around HSTS. We only recommend turning it on after every resource on a site is confirmed to load over HTTPS, because an HSTS header sent too early locks visitors out of the HTTP fallback for as long as the max-age specifies, with no quick way to undo it.
— Ihor
inSave Hosting: free SSL, easy redirects, and managed help
Setting up a correct HTTPS redirect is easier when the hosting underneath already includes a free SSL certificate and a panel built to handle the switch. We offer hosting plans that include free SSL certificates, one-click WordPress installations, and support to assist with certificate or redirect configuration, so you're not troubleshooting alone when a redirect rule doesn't behave as expected.

- Our shared hosting plans include free SSL and panel-level redirect options for anyone who wants HTTPS enforced without touching a config file.
- Our WordPress hosting adds staging environments and migration support, useful for catching mixed-content issues before they go live.
- Our VPS hosting gives full control over Apache or NGINX configuration for anyone who wants to write the server-level redirect themselves.
If you're moving an existing site, our team can help with migration so the redirect and SSL setup land correctly on the first try. For a broader look at avoiding traffic loss during a larger move, our migration checklist and BabyLoveGrowth's site migration SEO guide both cover URL mapping in more depth. Reach out through our support channels to get started.
FAQ
Should you redirect HTTP to HTTPS?
Yes. A permanent 301 redirect protects the search ranking signals already pointing at your HTTP pages and ensures visitors always land on the encrypted version of your site, which browsers increasingly expect by default.
How to force HTTP to HTTPS?
Add a 301 redirect at the server level: an Apache VirtualHost or .htaccess rule, or an NGINX server block with return 301 https://$host$request_uri. On shared hosting, a "Force HTTPS" toggle in your control panel does the same job without editing config files.
Will HTTP automatically redirect to HTTPS?
No, not unless a redirect rule, hosting panel setting, or HSTS header is explicitly configured. Without one of those in place, a browser will load the HTTP version of a page if that's the URL it was given.
Why does the browser redirect HTTP to HTTPS?
A browser only does this on its own when it has previously received an HSTS header from that domain, which instructs it to skip HTTP entirely for a set period. Otherwise, the redirect has to come from the server or hosting panel configuration.
Sources
- Redirect HTTP to HTTPS in Apache — Linuxize
- Mixed content - Security | MDN
- Ssl
- Apache 2.4 : HTTPS redirection excepted for ./well-known/acme-challenge — Let’s Encrypt Community
