Fix Guide

How to Add the HSTS Header in WordPress

February 8, 2026

The HSTS header (HTTP Strict Transport Security) tells browsers to only connect to your WordPress site over HTTPS. Without it, visitors could accidentally land on an insecure HTTP version of your page, leaving them vulnerable to man-in-the-middle attacks. Once the header is in place, browsers remember your preference and automatically upgrade every request to HTTPS for the duration you specify.

What Does the HSTS Header Actually Do?

When a browser receives the Strict-Transport-Security header, it stores that information locally. For every future visit within the specified max-age window, the browser will refuse to connect over plain HTTP. It does not even attempt an HTTP connection first; it goes straight to HTTPS. This eliminates the brief window where an attacker could intercept the initial HTTP request and redirect the user to a malicious page.

The header has three main parameters:

  • max-age: how long (in seconds) the browser should remember to force HTTPS. A value of 31536000 equals one year.
  • includeSubDomains: applies the rule to every subdomain as well (e.g., blog.example.com, shop.example.com).
  • preload: signals that you want your domain included in the browser's built-in HSTS preload list, so the very first visit is also protected.

Before You Start: Make Sure HTTPS Works Everywhere

This step is critical. Once HSTS is active, browsers will not let visitors fall back to HTTP. If your SSL certificate is expired, misconfigured, or missing on a subdomain, those pages become completely unreachable for the duration of your max-age setting. Before enabling anything, verify the following:

  • Your SSL certificate is valid and not close to expiring.
  • All pages on your site load correctly over https://.
  • There are no mixed-content warnings in the browser console (HTTP resources loaded on HTTPS pages).
  • If you plan to use includeSubDomains, every subdomain must have a valid certificate and serve content over HTTPS.
  • Your WordPress Site URL and WordPress Address (in Settings > General) both use https://.

Adding HSTS via Apache .htaccess

If your WordPress site runs on Apache (most shared hosting providers use Apache), you can add the header directly in the .htaccess file located in your WordPress root directory. Open the file with a text editor or your hosting provider's file manager, and add the following block before the # BEGIN WordPress section:

<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>

The IfModule wrapper ensures that Apache only processes this directive if mod_headers is enabled. On most hosts it is enabled by default, but the wrapper prevents a 500 error on servers where it is not available.

Adding HSTS via Nginx

For Nginx-based hosting (common with managed WordPress hosts like Kinsta, Cloudways, or SpinupWP), add the header inside your server block. The configuration file is usually located at /etc/nginx/sites-available/yourdomain.com or within a custom Nginx include directory provided by your host:

server {
    listen 443 ssl;
    server_name example.com;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # ... rest of your server config
}

The always keyword at the end is important. Without it, Nginx only sends the header on successful (2xx) responses. With always, it is included on error pages (4xx, 5xx) too, which is the correct behavior for security headers.

After editing the config, test and reload Nginx:

sudo nginx -t
sudo systemctl reload nginx

Adding HSTS via PHP in functions.php

If you do not have access to server configuration files (some managed hosts restrict this), you can send the header from PHP. Add the following to your active theme's functions.php file or, better yet, to a site-specific plugin so it survives theme updates:

function iwp_add_hsts_header() {
    if ( ! is_admin() ) {
        header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload' );
    }
}
add_action( 'send_headers', 'iwp_add_hsts_header' );

Keep in mind that PHP-based headers only apply to pages processed by WordPress. Static files (images, CSS, JS) served directly by Apache or Nginx will not carry this header. For complete coverage, the server-level approach is always better.

Using a WordPress Plugin to Set HSTS

If you prefer a no-code approach, several plugins can handle HSTS for you:

  • Really Simple SSL (Pro): the Pro version includes a security headers module where you can toggle HSTS on and configure max-age and includeSubDomains from the dashboard.
  • HTTP Headers: a free plugin that gives you a UI to set various security headers, including Strict-Transport-Security.
  • Headers Security Advanced & HSTS WP: specifically built for security headers with an easy toggle for HSTS and preload.

Plugins are convenient, but they add an extra dependency. If the plugin is deactivated or removed, your headers disappear too. For something as fundamental as HSTS, a server-level configuration is more reliable.

Safe Rollout Strategy: Start Small, Then Increase

Jumping straight to a one-year max-age is risky if you have not tested everything. If something goes wrong, browsers will keep forcing HTTPS for an entire year, and there is no way to "undo" the header from the server side once a browser has cached it. Follow this gradual approach instead:

  1. 5 minutes: set max-age=300 and browse your site. Check that every page loads, forms submit correctly, and no mixed-content warnings appear.
  2. 1 day: increase to max-age=86400. Let it run for a day or two while monitoring your site.
  3. 1 week: bump to max-age=604800. At this point, you should feel confident that HTTPS works everywhere.
  4. 1 year: set the final value of max-age=31536000. This is the minimum required for HSTS preload submission.
  5. Add includeSubDomains: only do this once all subdomains are confirmed to work on HTTPS.
  6. Add preload: add the preload flag and submit your domain at hstspreload.org.

Submitting Your Site to the HSTS Preload List

The HSTS preload list is a directory of domains that browsers ship with built-in HSTS enforcement. This means even the very first visit to your site will be over HTTPS, before the browser has ever seen your header. To qualify, your site must meet these requirements:

  • Serve a valid SSL certificate.
  • Redirect all HTTP traffic to HTTPS on the same host.
  • Send the Strict-Transport-Security header with max-age of at least 31536000 (one year).
  • Include the includeSubDomains directive.
  • Include the preload directive.

Visit hstspreload.org, enter your domain, and submit. Be aware that removal from the preload list takes months and requires a browser update cycle, so only submit when you are fully committed to HTTPS.

How to Verify Your HSTS Header with Browser DevTools

After adding the header, you can quickly confirm it is working:

  1. Open your site in Chrome or Firefox.
  2. Press F12 to open DevTools.
  3. Go to the Network tab and reload the page.
  4. Click on the main document request (usually the first one).
  5. Scroll down to Response Headers.
  6. Look for Strict-Transport-Security. You should see your configured value.

You can also use the command line to check:

curl -sI https://example.com | grep -i strict-transport

If the header does not appear, double-check that you are visiting the HTTPS version (not HTTP) and that your server configuration changes have been saved and reloaded.

Common HSTS Mistakes and How to Avoid Them

  • Setting HSTS on HTTP responses: the header is ignored by browsers when served over plain HTTP. It only takes effect on HTTPS responses.
  • Forgetting static file coverage: if you set HSTS via PHP, static files bypass WordPress and will not carry the header. Use server-level configuration for full coverage.
  • Using includeSubDomains without checking subdomains: if you have a subdomain that does not support HTTPS (e.g., an old staging server), it will become inaccessible.
  • Jumping to a long max-age too quickly: always start with a short duration and work your way up.
  • Forgetting to renew your SSL certificate: with HSTS active and an expired certificate, your site is completely unreachable. Set up auto-renewal with Let's Encrypt or your certificate provider.

Verify Your HSTS Setup with InspectWP

After adding the header, run a new InspectWP scan on your site. The security headers section of your report will show the Strict-Transport-Security header status. If everything is configured correctly, it will appear as green (present). If you have also set up other security headers, check those as well to get a complete picture of your site's security posture.

Check your WordPress site now

InspectWP analyzes your WordPress site for security issues, SEO problems, GDPR compliance, and performance — for free.

Analyze your site free