TLS / HTTPS
Weight: 5% of your AX score. Many AI agents refuse to fetch plaintext HTTP and downgrade trust on misconfigured TLS. This check verifies HTTPS, the HTTP→HTTPS redirect, and HSTS configuration including preload eligibility.
Invalid URL
Pass a fully qualified URL including scheme: npx ax-audit https://your-site.com. Bare hostnames like your-site.com are rejected.
Site not served over HTTPS
Your site responds to HTTP only. AI crawlers and most agents refuse plaintext origins.
- Free option: Let's Encrypt + Certbot on your server, or your hosting provider's built-in TLS (Vercel, Netlify, Cloudflare, Render, Fly.io all give it for free).
- Cloudflare Universal SSL: proxy your domain through Cloudflare for instant HTTPS.
- Self-hosted: Caddy auto-provisions and renews certificates with zero config.
HTTP does not redirect to HTTPS
A request to http://your-site.com returned content over plain HTTP instead of redirecting. Agents may cache the insecure variant.
# Nginx
server {
listen 80;
server_name your-site.com www.your-site.com;
return 301 https://your-site.com$request_uri;
}
# Apache (.htaccess)
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Caddy
http://your-site.com {
redir https://your-site.com{uri} permanent
}Redirect could not be verified
ax-audit got an unexpected response from the HTTP endpoint and couldn't determine the redirect behavior. Test manually:
curl -I http://your-site.com # Expected: HTTP/1.1 301 Moved Permanently # Location: https://your-site.com/
No HSTS header
Strict-Transport-Security instructs browsers and agents to use HTTPS for all future requests for a fixed period. Without it, the very first connection on a new device can still be downgraded.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
# Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Express
app.use((req, res, next) => {
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
next();
});
# Vercel (vercel.json)
{
"headers": [{
"source": "/(.*)",
"headers": [{
"key": "Strict-Transport-Security",
"value": "max-age=31536000; includeSubDomains; preload"
}]
}]
}HSTS missing max-age
Your HSTS header has no max-age directive — without it the header is effectively ignored. Set a numeric value in seconds:
Strict-Transport-Security: max-age=31536000
HSTS max-age too short
A max-age below ~6 months is too short to provide meaningful protection. The browser preload list requires at least 1 year (31536000 seconds).
Recommended values: max-age=63072000 (2 years) for production, max-age=300 only while testing.
HSTS missing includeSubDomains
includeSubDomains applies HSTS to api.your-site.com, docs.your-site.com, etc. — without it, an attacker can downgrade http://api.your-site.com even when the apex is locked to HTTPS.
max-age period.HSTS missing preload directive
Adding preload to the HSTS header signals you want to be added to the browser preload list — a hard-coded list of HTTPS-only domains shipped with Chromium, Firefox, Safari, and Edge.
After adding the directive and confirming the preload requirements, submit the domain at hstspreload.org.
HSTS preload not eligible
The preload directive is set but the header doesn't satisfy the preload list requirements. To be eligible:
max-agemust be at least31536000(1 year).includeSubDomainsmust be present.preloadmust be present.- The apex domain must redirect from HTTP to HTTPS.
- All subdomains must serve HTTPS.
Verify your status at hstspreload.org.