Fix "You’re Accessing the Development Server Over HTTPS"
Fix the Django runserver error saying you’re accessing the development server over HTTPS but it only supports HTTP: clear cached HSTS, turn off SSL redirects in development, avoid .dev domains, and run local HTTPS properly when you need it.
Problem statement
You open your local project and the page never loads. The terminal running runserver fills with lines like these:
[03/Oct/2026 10:12:44] code 400, message Bad request version ('\x16\x03\x01\x02\x00\x01...')
[03/Oct/2026 10:12:44] You're accessing the development server over HTTPS, but it only supports HTTP.
The browser is speaking TLS to a server that only speaks plain HTTP. The \x16\x03\x01 bytes are the start of a TLS handshake. Usually nothing is wrong with Django: the browser has been told to always use HTTPS for this host, by an HSTS header your own settings sent earlier, by the domain's top-level suffix, or by a redirect it cached.
- Type the URL explicitly as
http://127.0.0.1:8000/, notlocalhostwith a cached redirect. - Set
SECURE_SSL_REDIRECT = FalseandSECURE_HSTS_SECONDS = 0in development settings. - Clear the cached HSTS entry: in Chrome open
chrome://net-internals/#hstsand deletelocalhost; in Firefox forget the site from history. - Do not use
.dev,.app, or other HSTS-preloaded domains for local hosts; use.localhostor.test. - If you need HTTPS locally, put a TLS proxy such as Caddy in front of runserver, or use
runserver_pluswith a certificate.
Step-by-step solution
1. Confirm the browser is the one upgrading
Open a private window and visit http://127.0.0.1:8000/. If it works there, the normal window has cached either a redirect or an HSTS policy for the host. Also try curl, which never uses browser HSTS:
curl -I http://127.0.0.1:8000/
A 200 or 302 to a normal path means runserver is fine. A 301 to https://... means your settings are redirecting, which is step 2.
2. Turn off HTTPS settings in development
Production settings usually include:
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 31536000
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
If these leak into local development, the first request redirects to HTTPS and the HSTS header tells the browser to stick to HTTPS for a year. Keep them in production settings only, or read them from the environment with safe defaults:
# settings/development.py
from .base import * # noqa
DEBUG = True
SECURE_SSL_REDIRECT = False
SECURE_HSTS_SECONDS = 0
SESSION_COOKIE_SECURE = False
CSRF_COOKIE_SECURE = False
3. Clear the cached HSTS policy
HSTS is stored per host name. Removing the setting does not remove the browser's memory of it.
- Chrome and Edge: open
chrome://net-internals/#hsts, typelocalhost(or your custom host) under Delete domain security policies, and click Delete. - Firefox: open History, find the site, right-click, and choose Forget About This Site.
- Safari: remove the host from
~/Library/Cookies/HSTS.plistwhile Safari is closed.
Then load http://localhost:8000/ again. Using 127.0.0.1 instead of localhost is a quick workaround, because the policy was stored for the name, not the address.
4. Pick a local host name that is not HSTS preloaded
Every host under .dev and .app is on the browser HSTS preload list, so no browser will ever request them over HTTP. myproject.dev cannot work with runserver no matter what you clear. Use names under .localhost, which resolve to the loopback address in modern browsers, or .test, which is reserved for testing:
ALLOWED_HOSTS = ["localhost", "127.0.0.1", ".localhost", ".test"]
5. Run HTTPS locally when you really need it
Some features, such as secure cookies, OAuth callbacks, and service workers on custom hosts, need HTTPS even in development. Do not point the browser at runserver over HTTPS; terminate TLS in front of it. With Caddy:
caddy reverse-proxy --from myproject.localhost --to 127.0.0.1:8000
Caddy issues a locally trusted certificate and proxies plain HTTP to runserver. Alternatively, django-extensions provides runserver_plus --cert-file cert.pem, which serves TLS itself using Werkzeug.
Explanation
runserver uses Python's simple HTTP server, which has no TLS support. When a browser opens an HTTPS connection to port 8000, the first bytes it sends are a TLS ClientHello. Django tries to parse them as an HTTP request line, fails, logs code 400 with the binary bytes, and prints the hint about HTTPS. The browser shows a connection error because it never gets a TLS response.
The browser chose HTTPS because of HSTS (Strict-Transport-Security), a cached permanent redirect, a preloaded top-level domain, or simply an https:// URL you typed or bookmarked. HSTS is the stubborn one: once received, it applies for max-age seconds even after you remove the header from your settings.
Edge cases / notes
- This error in production. If production logs show this message, you are running
runserverbehind a proxy that forwards HTTPS to it. Replace runserver with Gunicorn or Uvicorn; see Why Not Use runserver in Production. - Docker port mapping. A local Nginx or Traefik container configured with
proxy_pass https://web:8000causes the same error. Usehttp://for the upstream. - includeSubDomains. An HSTS header with
includeSubDomainssent fromexample.comalso coverslocal.example.com. Avoid using real domains for local development.
Next steps
- Structure settings so production security flags never reach development: Split Django Settings for Development and Production.
- For redirect loops on real servers, see Fix Django Too Many Redirects With HTTPS.
- Roll out HSTS safely in production with the Django Security Headers Checklist.
FAQ
Why does it work with 127.0.0.1 but not localhost?
HSTS policies are stored per host name. The browser remembered the policy for localhost, so the numeric address bypasses it.
Can I make runserver support HTTPS?
Not the built-in one. Use a TLS proxy such as Caddy in front of it, or runserver_plus from django-extensions.
Will turning off SECURE_HSTS_SECONDS fix the browser immediately?
No. It stops new policies, but the browser keeps the old one until it expires or you delete it manually.
Is it safe to disable these settings?
In development, yes. Keep SECURE_SSL_REDIRECT, HSTS, and secure cookies enabled in production settings.