Django RuntimeError: populate() isn't reentrant (tested)

RuntimeError: populate() isn't reentrant means django.setup() ran again after an earlier attempt failed or while it was still running. The message hides the real error: look for the first traceback.

1. The usual cause: a second setup() after the first one failed

proj/brokenapp/models.py contains one line, import nonexistent_package.

import sys; sys.path.insert(0, '/w/proj')
import django
from django.conf import settings
settings.configure(INSTALLED_APPS=['brokenapp'])
for attempt in (1, 2):
    try:
        django.setup()
    except Exception as e:
        print(f'setup() attempt {attempt}:', type(e).__name__ + ':', e)

Output:

setup() attempt 1: ModuleNotFoundError: No module named 'nonexistent_package'
setup() attempt 2: RuntimeError: populate() isn't reentrant

The first setup() fails with the real error. Django has already marked the app registry as loading, so any later setup() in the same process raises RuntimeError: populate() isn't reentrant instead of the original error. If your server retries loading wsgi.py in the same process after a failed import (Apache mod_wsgi does this on the next request), the second and later requests show only this message.

Fix: find the first error. Scroll up in the server log to the first traceback after the restart, or run python manage.py check (or python -c "import django; django.setup()" with your DJANGO_SETTINGS_MODULE) in the same virtualenv. The underlying error is typically a missing package, a typo in INSTALLED_APPS, or an exception in a models.py. Then restart the server process.

2. setup() called while setup() is running

proj/selfsetup/apps.py:

from django.apps import AppConfig
class SelfSetupConfig(AppConfig):
    name = 'selfsetup'
    def ready(self):
        import django
        django.setup()            # setup() called while setup() is running
import sys; sys.path.insert(0, '/w/proj')
import django
from django.conf import settings
settings.configure(INSTALLED_APPS=['selfsetup'])
try:
    django.setup()
except Exception as e:
    print(type(e).__name__ + ':', e)

Output:

RuntimeError: populate() isn't reentrant

The same error appears when code imported during setup (an AppConfig.ready(), a models.py, or a module they import) calls django.setup() again. Only call django.setup() once, in a standalone script's entry point, never inside app code.

Related: Django ImproperlyConfigured: settings are not configured, Django TemplateDoesNotExist.

Frequently asked questions

What causes populate() isn't reentrant in Django?

django.setup() ran again in a process where an earlier setup() failed or is still running. The first failure, often an ImportError in an installed app, is the real error.

How do I see the real error behind populate() isn't reentrant?

Read the first traceback in the server log after restart, or run python manage.py check in the same environment.

Written with AI assistance. Measured on 2026-10-23 with Django 6.1.2 and Python 3.14.7 (python:3-alpine in Docker). Each block was run verbatim and the output pasted unedited. PlainHeaders is our extension; Python and Django are free.