Django ALLOWED_HOSTS: values, wildcards and DisallowedHost errors
verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated 2026-10-20
- tool
- Django
- file
- settings.py
- key
- ALLOWED_HOSTS
- type
- list of strings
- default
- [] (with DEBUG = True and an empty list, .localhost, 127.0.0.1 and [::1] are allowed)
ALLOWED_HOSTS is the list of host names your Django site answers to. Django compares the request's Host header against it and rejects any other value with DisallowedHost, which becomes a 400 Bad Request. In production (DEBUG = False) the list must contain your domain names.
What Django checks
python -c '
import django
from django.conf import settings
settings.configure(DEBUG=False, ALLOWED_HOSTS=["example.com", ".api.example.com"], SECRET_KEY="dev")
django.setup()
from django.test import RequestFactory
from django.core.exceptions import DisallowedHost
for host in ["example.com", "v2.api.example.com", "api.example.com", "evil.example.net"]:
try:
print(f"{host:20} allowed ->", RequestFactory().get("/", HTTP_HOST=host).get_host())
except DisallowedHost as e:
print(f"{host:20} rejected:", e)'Output
example.com allowed -> example.com v2.api.example.com allowed -> v2.api.example.com api.example.com allowed -> api.example.com evil.example.net rejected: Invalid HTTP_HOST header: 'evil.example.net'. You may need to add 'evil.example.net' to ALLOWED_HOSTS.
Value syntax
| Entry | Matches |
|---|---|
| "example.com" | exactly example.com (case-insensitive, any port) |
| ".example.com" | example.com and every subdomain |
| "*" | any host: disables the check (avoid in production) |
| "192.0.2.10" | requests to that IP address |
Typical production setting
import os
DEBUG = False
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "example.com,www.example.com").split(",")Behind a reverse proxy, Django sees the Host header the proxy forwards; set USE_X_FORWARDED_HOST = True only if the proxy sets X-Forwarded-Host and you trust it.
Sources
Related pages
errors · djangoImproperlyConfigured: Requested setting …, but settings are not configuredDjango raises ImproperlyConfigured when code reads settings before DJANGO_SETTINGS_MODULE is set or settings.configure() runs. Set it, then call django.setup().cheat sheets · djangoDjango manage.py cheat sheet: project, migrations, users, testingDjango manage.py cheat sheet: startproject and startapp, makemigrations and migrate, createsuperuser, runserver, shell, check, test, collectstatic and dumpdata.codes · djangoDjango HttpResponse subclasses and their status codesDjango HttpResponse subclasses and their status codes: Redirect 302, PermanentRedirect 301, NotModified 304, BadRequest 400, Forbidden 403, NotFound 404.