Skip to main content

Django 500 Internal Server Error in production — triage guide

TL;DR

How to triage Django 500 errors in production when DEBUG is False and tracebacks are hidden from users.

Key facts

Topic
Production error triage
Stack
Django / Gunicorn / Linux

TL;DR

A Django 500 Internal Server Error in production means an unhandled exception reached Django's error middleware. With DEBUG=False (mandatory in production), users see a generic error page while the traceback goes to your configured error handler — Sentry, log files, or the ADMINS email list.

Common causes

  • A missing or incorrect DJANGO_SETTINGS_MODULE environment variable
  • Database migrations not applied after deployment (python manage.py migrate)
  • A missing environment variable referenced in settings.py
  • Template syntax errors or missing template files
  • Import errors from missing Python packages (incomplete pip install)

Diagnosis workflow

Check the application logs first:

journalctl -u gunicorn --since "10 minutes ago"
tail -200 /var/log/django/error.log

Test the deployment manually:

cd /var/www/myapp
source venv/bin/activate
python manage.py check --deploy
python manage.py showmigrations | grep '\[ \]'

Quick fixes

Apply pending migrations:

python manage.py migrate --noinput

Verify all required environment variables are set:

python manage.py diffsettings

Collect static files if they are missing:

python manage.py collectstatic --noinput

Production hardening

  • Always configure Sentry (sentry-sdk[django]) for real-time error tracking with full stack traces
  • Set ALLOWED_HOSTS explicitly — a missing entry causes 400 or 500 errors on valid requests
  • Use python manage.py check --deploy in your CI pipeline to catch misconfigurations before production
  • Configure structured logging so errors include request context (URL, user, timestamp)

Where Reflex helps

Reflex monitors your Gunicorn error logs and HTTP 500 rate. When the 500 rate spikes, Reflex can run manage.py check, verify database connectivity, apply pending migrations, restart Gunicorn workers, and confirm the error rate drops — all in a documented, auditable playbook. See How it works.