affaan-m/ECC · critical · ImproperlyConfigured

DJANGO_SECRET_KEY environment variable is required

Error message

DJANGO_SECRET_KEY environment variable is required

What it means

The django-security skill's settings example reads SECRET_KEY from the DJANGO_SECRET_KEY env var and raises django.core.exceptions.ImproperlyConfigured if it is missing. This is a security best-practice snippet: the secret must be provisioned out-of-band, and Django fails fast at startup rather than running with a default/insecure key. Because settings load on every management command, this guard fires at process start, not at request time.

Source

Thrown at skills/django-security/SKILL.md:52

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 31536000  # 1 year
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_BROWSER_XSS_FILTER = True
X_FRAME_OPTIONS = 'DENY'

# HTTPS and Cookies
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Lax'
CSRF_COOKIE_SAMESITE = 'Lax'

# Secret key (must be set via environment variable)
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
if not SECRET_KEY:
    raise ImproperlyConfigured('DJANGO_SECRET_KEY environment variable is required')

# Password validation
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'OPTIONS': {
            'min_length': 12,
        }
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Set DJANGO_SECRET_KEY in the environment for every process that loads settings.
  2. Generate a key: python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())".
  3. Load .env via django-environ / python-dotenv before settings read os.environ.
  4. Use a distinct secret per environment (dev/staging/prod); never commit it.

Example fix

// before
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
if not SECRET_KEY:
    raise ImproperlyConfigured('DJANGO_SECRET_KEY environment variable is required')

// after — allow dev fallback while still failing in non-dev
import os
from django.conf import settings as django_settings
from django.core.exceptions import ImproperlyConfigured

SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
if not SECRET_KEY:
    if django_settings.DEBUG:
        from django.core.management.utils import get_random_secret_key
        SECRET_KEY = get_random_secret_key()
    else:
        raise ImproperlyConfigured('DJANGO_SECRET_KEY environment variable is required')
Defensive patterns

Strategy: validation

Validate before calling

import os, sys

def secret_key_provisioned() -> bool:
    return bool(os.environ.get("DJANGO_SECRET_KEY")) or "test" in sys.argv

Try / catch

from django.core.exceptions import ImproperlyConfigured

try:
    from myproject.settings import *  # noqa
except ImproperlyConfigured as e:
    if "DJANGO_SECRET_KEY" in str(e):
        print("Set DJANGO_SECRET_KEY in the environment")
    raise

Prevention

When it happens

Trigger: Starting Django (runserver/gunicorn/management command) without DJANGO_SECRET_KEY in the environment; .env file not loaded before settings access os.environ; SECRET_KEY hardcoded default removed in favor of this guard.

Common situations: Fresh deploy missing the secret in the environment; .env not sourced in the WSGI/ASGI process; CI running manage.py without the secret; Docker image missing the env var; local dev after switching from a hardcoded key to env-based.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/21e957c37cd64300. Report an issue: GitHub.