django/django · error · CommandError
You must set settings.ALLOWED_HOSTS if DEBUG is False.
Error message
You must set settings.ALLOWED_HOSTS if DEBUG is False.
What it means
Raised by runserver when settings.DEBUG is False and settings.ALLOWED_HOSTS is empty. Django refuses to serve because ALLOWED_HOSTS is a critical security control against HTTP Host header spoofing; with DEBUG off there is no safety net. The check is at the top of handle() before any address/port parsing happens.
Source
Thrown at django/core/management/commands/runserver.py:81
def execute(self, *args, **options):
if options["no_color"]:
# We rely on the environment because it's currently the only
# way to reach WSGIRequestHandler. This seems an acceptable
# compromise considering `runserver` runs indefinitely.
os.environ["DJANGO_COLORS"] = "nocolor"
super().execute(*args, **options)
def get_handler(self, *args, **options):
"""Return the default WSGI handler for the runner."""
return get_internal_wsgi_application()
def get_check_kwargs(self, options):
"""Validation is called explicitly each time the server reloads."""
return {"tags": set()}
def handle(self, *args, **options):
if not settings.DEBUG and not settings.ALLOWED_HOSTS:
raise CommandError("You must set settings.ALLOWED_HOSTS if DEBUG is False.")
self.use_ipv6 = options["use_ipv6"]
if self.use_ipv6 and not socket.has_ipv6:
raise CommandError("Your Python does not support IPv6.")
self._raw_ipv6 = False
if not options["addrport"]:
self.addr = ""
self.port = self.default_port
else:
m = re.match(naiveip_re, options["addrport"])
if m is None:
raise CommandError(
'"%s" is not a valid port number '
"or address:port pair." % options["addrport"]
)
self.addr, _ipv4, _ipv6, _fqdn, self.port = m.groups()
if not self.port.isdigit():
raise CommandError("%r is not a valid port number." % self.port)View on GitHub (pinned to ae25a40be0)
Solutions
- Add ALLOWED_HOSTS = ['127.0.0.1', 'localhost'] (or your actual host) to the settings module used for runserver.
- If this is local dev only, keep DEBUG=True so the check is bypassed.
- Verify DJANGO_SETTINGS_MODULE points to the intended settings file; set it explicitly if a wrong module is loaded.
Example fix
# before DEBUG = False ALLOWED_HOSTS = [] # after DEBUG = False ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
Defensive patterns
Strategy: validation
Validate before calling
from django.conf import settings
if not settings.DEBUG and not settings.ALLOWED_HOSTS:
raise SystemExit('Set ALLOWED_HOSTS before running runserver with DEBUG=False') Prevention
- Always set ALLOWED_HOSTS in non-dev settings files, even if just to ['localhost'].
- Use environment-variable-driven settings (e.g. ALLOWED_HOSTS = os.environ['ALLOWED_HOSTS'].split(',')) so config is explicit per environment.
- Run a settings sanity check in CI before booting runserver against staging settings.
When it happens
Trigger: Running `python manage.py runserver` while DEBUG=False in settings and ALLOWED_HOSTS = []. This commonly happens when an environment-specific settings file or DJANGO_SETTINGS_MODULE points at production-like settings without configuring ALLOWED_HOSTS.
Common situations: Switching from dev settings to a staging/prod settings module, setting DEBUG=False via environment variable, or a CI job that boots runserver against production settings. Also seen when DJANGO_SETTINGS_MODULE is accidentally set to the wrong module.
Related errors
- The SECRET_KEY setting must not be empty.
- password_too_short
- password_too_similar
- password_too_common
- password_entirely_numeric
AI-assisted analysis of django/django@ae25a40be0 (2026-08-06).
Data as JSON: /api/errors/d9cec4706d1f58ca.
Report an issue: GitHub.