django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
Python · updated 2026-11-04
Raised by Django when settings are loaded and SECRET_KEY is empty or missing. Most settings files read it from an environment variable, so this means the variable is not set in that environment: the container, the systemd unit, the CI job, or a Docker build step that runs manage.py.
Traceback (most recent call last):
File "/app/manage.py", line 22, in <module>
main()
...
File "/usr/local/lib/python3.12/site-packages/django/conf/__init__.py", line 143, in __setattr__
raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.Quick fix
Set the variable your settings read (for example DJANGO_SECRET_KEY) in the environment that runs Django, from your platform's secret store. Read it with os.environ['DJANGO_SECRET_KEY'] so a missing value fails with that name instead of an empty default. If it fails only during docker build (collectstatic), pass a throwaway value for that one command.
- Open settings.py and find how SECRET_KEY is read (os.environ, django-environ, python-decouple).
- Set that variable where Django runs: the container env, the platform secret, the systemd EnvironmentFile.
- Check DJANGO_SETTINGS_MODULE points at the settings file you expect (production vs local).
- If a .env file is meant to load it, confirm it exists in the container and is loaded before settings are read.
- For collectstatic in a Dockerfile: RUN DJANGO_SECRET_KEY=build-only python manage.py collectstatic --noinput.
# settings.py
import os
# Fails with KeyError: 'DJANGO_SECRET_KEY' if it's missing, which names the variable.
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
# Generate a value once and store it in your secret manager:
# python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"Why it happens
The variable is not set in production
os.environ.get("DJANGO_SECRET_KEY") returns None or an empty default, and Django refuses it. Common after moving to a new host or container platform.
manage.py during the image build
collectstatic or compilemessages in a Dockerfile runs before the runtime secrets exist, so settings load without the key.
The wrong settings module
DJANGO_SETTINGS_MODULE points at a production settings file that expects the variable, while it is only set for the local one (or the reverse).
.env not loaded
django-environ or python-decouple read a .env file that is excluded from the image or sits in a different working directory.
Other fixes
- Don't commit a real SECRET_KEY to settings.py: rotating it after a leak invalidates sessions and password reset links.
- python manage.py check --deploy flags a missing or weak SECRET_KEY and other production settings.
Same error, other wording
- django.core.exceptions.ImproperlyConfigured: Requested setting DEBUG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
- KeyError: 'DJANGO_SECRET_KEY'
- django.core.exceptions.ImproperlyConfigured: Set the SECRET_KEY environment variable
Let your coding agent catch the next one
Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:
> Find the "SECRET_KEY setting must not be empty" errors, tell me which environment variable settings.py reads and where the process runs, and fix the deployment so the variable is set there (and the build step gets a throwaway value if it runs manage.py).
Related errors
- django.db.utils.OperationalError: no such table: orders_order
- ModuleNotFoundError: No module named 'x'
- KeyError: 'email'
More in Memory, async and the process
- [UnhandledPromiseRejection: This error originated either by throwing inside of an async...Node.js
- FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memoryNode.js
- RangeError: Maximum call stack size exceededNode.js
- RecursionError: maximum recursion depth exceededPython
- RuntimeError: Event loop is closedPython
- RuntimeWarning: coroutine 'fetch_user' was never awaitedPython
- Error: listen EADDRINUSE: address already in use :::3000Node.js
- OSError: [Errno 98] Address already in usePython
- Error: error:0308010C:digital envelope routines::unsupportedNode.js
- MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 error...Node.js
- Error: ENOENT: no such file or directory, open '/app/config.json'Node.js
- Error: EACCES: permission denied, open '/app/data/cache.json'Node.js
- Error: EMFILE: too many open files, open '/app/uploads/0412.jpg'Node.js
- PermissionError: [Errno 13] Permission denied: '/app/data/report.csv'Python
- CredentialsProviderError: Could not load credentials from any providersNode.js
- botocore.exceptions.NoCredentialsError: Unable to locate credentialsPython
References: Django docs: settings (SECRET_KEY), Django docs: deployment checklist, Django source: where the error is raised