Leaving DEBUG = True in production makes Django show detailed error pages that include source code excerpts, local variables, settings and the libraries in use. That is a map of your application handed to anyone who can trigger an error. Set DEBUG to False, set ALLOWED_HOSTS, and send errors to logging instead.
What the Django docs say it leaks
The deployment checklist is blunt: you must never enable debug in production. It explains that DEBUG = True is convenient in development because it gives full tracebacks in the browser, but in production it "leaks lots of information about your project", listing excerpts of your source code, local variables, settings and libraries used.
Think about what each item is worth to an attacker:
| Leaked item | Why it helps an attacker |
|---|---|
| Source excerpts | Shows logic, query construction and validation gaps |
| Local variables | Can include tokens, user data and connection details |
| Settings | Reveals installed apps, middleware, paths and debug flags |
| Library list | Lets them match versions against known advisories |
You do not need a vulnerability for this to matter. Any unhandled exception, even one an attacker provokes with a malformed request, becomes a reconnaissance report.
Why it stays on by accident
Most cases are not careless. They come from a shared settings file where DEBUG defaults to True, an environment variable that parses the string "False" as truthy, a staging server that became production, or a hotfix someone forgot to revert. Because the site works fine with debug on, nothing breaks to warn you.
A safer pattern is to default to False and require an explicit opt in:
import os
DEBUG = os.environ.get("DJANGO_DEBUG", "") == "1"
With this, a missing variable means production behavior.
How to check a running site
- Run
python manage.py check --deployagainst your production settings file. The checklist says it automates some of its checks. - In a staging copy, trigger a harmless error and confirm you see a plain error page.
- Search your repositories and images for settings files that hardcode DEBUG = True.
What to do instead of debug pages
Django's error reporting guide says to turn DEBUG off on public sites, and that running with DEBUG False means you will not see errors unless you configure reporting. When DEBUG is False and the ADMINS setting is configured with working email, Django emails administrators for responses with status 500 or above. Better still, send exceptions to your logging or error tracking system. Use the sensitive_variables and sensitive_post_parameters decorators so reports do not carry secrets.
Also note that DEBUG = False requires ALLOWED_HOSTS to be set, because Django does not work without a suitable value in that mode.
Try it yourself
Click through it at your own pace, or open it full screen. Watch how a running web app is probed from the outside, the same view an attacker has of a debug page.
Quick check
Is DEBUG = True a vulnerability or a misconfiguration?
A misconfiguration. Django is working as designed, but the information it exposes helps an attacker find real weaknesses.
Does check --deploy catch it?
It automates some of the deployment checklist, and Django says to run it against your production settings file. Treat it as a helper, and still review DEBUG yourself.
Safeguard's SAST and policy gates can flag hardcoded debug flags in a pull request, and compliance evidence automation can record the check. A free scan is available.
Sources
Last reviewed: 19 October 2026.