How to check HSTS preload status

Two separate facts. Read the header with curl and look for the preload token next to a max-age of at least 31536000 and includeSubDomains; that is the site asking to be listed. Whether the domain is actually on the list is answered only by https://hstspreload.org/?domain=<host>, which reads the current list.

Why check this

The preload list is the only thing that protects the first request a browser ever makes to a host. A site can carry every preload token and still be absent from the list, because entries are added by manual submission and removed when the requirements stop being met. Run this check before you tell a compliance reviewer the domain is preloaded, and again after a domain moves to a new CDN, which is when the apex commonly starts serving a shorter max-age and quietly stops qualifying.

Prerequisites

Steps

  1. Step 1.

    Read the header and confirm the preload token is present.

    curl -s -o /dev/null -D - https://api.github.com/ | grep -i 'strict-transport-security'
    
    strict-transport-security: max-age=31536000; includeSubdomains; preload

    All three parts have to be there. A header with max-age and includeSubDomains but no preload is a site that has not asked to be listed.

  2. Step 2.

    Check the max-age on the registrable domain itself against the one-year floor.

    curl -s -o /dev/null -D - https://cloudflare.com/ | grep -i -E '^HTTP/|^location|strict-transport-security'
    
    HTTP/2 301
    location: https://www.cloudflare.com/
    strict-transport-security: max-age=15780000; includeSubDomains

    15780000 seconds is 182 days, under half the required year, and there is no preload token. This apex does not qualify today.

  3. Step 3.

    Confirm that the plain HTTP request on the apex lands on HTTPS on the same host.

    curl -s -o /dev/null -D - http://cloudflare.com/ | grep -i -E '^HTTP/|^Location'
    
    HTTP/1.1 301 Moved Permanently
    Location: https://www.cloudflare.com/

    The first hop changes the scheme and the host in one move. The requirements ask for https://cloudflare.com/ first, so this is a second reason the apex would be rejected.

  4. Step 4.

    Open https://hstspreload.org/?domain=cloudflare.com in a browser and read the status block at the top of the page.

    That page is the authoritative answer. The list is a static file compiled into Chromium and mirrored by other browsers, so no header on your server can prove or disprove membership. The page reports whether the domain is currently on the list, whether it is queued for the next release, and which of the requirements it fails.

How to read the result

| What you see | What it means | What to do | | --- | --- | --- | | Header has max-age, includeSubDomains and preload | The server meets the header requirement | Confirm membership on the list page. The header is a request, not a receipt. | | preload token but max-age under 31536000 | The submission is rejected on the header | Raise max-age on the registrable domain first. | | preload token and the domain is not on the list | Nobody submitted it, or it was removed | Check the list page for the reason before resubmitting. | | No preload token but the list page says listed | The domain is protected and cannot be removed quickly | Removal takes months to reach stable browsers. Do not treat it as a config toggle. | | The apex redirects straight to www over HTTP | The same-host redirect requirement fails | Add http://domain to https://domain as the first hop. |

Common mistakes

Sign: The header carries preload, so the release notes record the domain as preloaded.Cause: The token only marks consent to be listed. Membership comes from a submission that a maintainer accepted and that shipped in a browser release, which can be weeks after the header changed.
Sign: A subdomain is checked on the list page and reports nothing useful.Cause: Entries cover a registrable domain and everything below it. Querying shop.example.com answers a question the list does not store. Query example.com instead.
Sign: Preload is switched on, then an internal host that has no certificate stops resolving for the whole team.Cause: includeSubDomains covers every name under the domain, including intranet and staging hosts that were only ever served over HTTP. Inventory subdomains before submitting, because removal from the list is slow.

Thresholds

max-age=31536000 seconds, one year, on the registrable domain, plus includeSubDomains and preload Source: https://hstspreload.org/
The first hop from http://domain must reach https://domain on the same host before any redirect to www Source: https://hstspreload.org/

What to check next

FAQ

How to check if a domain is in the HSTS preload list?

Query https://hstspreload.org/?domain=example.com and read the status block. The list ships inside the browser binary, so no request to your own server can answer the question, and no response header on your side changes the answer.

Does the preload token do anything on its own?

No. Browsers ignore it at runtime. It exists so a maintainer can confirm the domain owner consented before adding the entry.

How long does removal take?

Removal is requested on the same site and then has to reach a stable browser release, which is measured in months rather than days. Plan the certificate for every subdomain before submitting.

Which hostname do I submit?

The registrable domain. An entry for example.com with includeSubDomains already covers www.example.com and every other name below it.

Verified

Verified by Maks Vernycurl 8.21.0

Each output block is what the command above it printed on that date, on the host named in the step. Figures read from a live site move between runs. Compare the shape of the answer rather than the digits, and see the methodology for how a page is re-verified.

intermediate6 minpublished updated Maks Verny