django/django · critical · ImproperlyConfigured

SpatiaLite requires SQLite to be configured to allow extensi

Error message

SpatiaLite requires SQLite to be configured to allow extension loading.

What it means

Raised as ImproperlyConfigured when the underlying Python sqlite3 connection object has no enable_load_extension method (it raised AttributeError). SpatiaLite is loaded into SQLite at runtime as an extension, so the Python SQLite build must be compiled with extension loading enabled. Without that capability GeoDjango cannot load libspatialite at all.

Source

Thrown at django/contrib/gis/db/backends/spatialite/base.py:46

        self.lib_spatialite_paths = [
            name
            for name in [
                getattr(settings, "SPATIALITE_LIBRARY_PATH", None),
                "mod_spatialite.so",
                "mod_spatialite",
                find_library("spatialite"),
            ]
            if name is not None
        ]
        super().__init__(*args, **kwargs)

    def get_new_connection(self, conn_params):
        conn = super().get_new_connection(conn_params)
        # Enabling extension loading on the SQLite connection.
        try:
            conn.enable_load_extension(True)
        except AttributeError:
            raise ImproperlyConfigured(
                "SpatiaLite requires SQLite to be configured to allow "
                "extension loading."
            )
        # Load the SpatiaLite library extension on the connection.
        for path in self.lib_spatialite_paths:
            try:
                conn.load_extension(path)
            except Exception:
                if getattr(settings, "SPATIALITE_LIBRARY_PATH", None):
                    raise ImproperlyConfigured(
                        "Unable to load the SpatiaLite library extension "
                        "as specified in your SPATIALITE_LIBRARY_PATH setting."
                    )
                continue
            else:
                break
        else:
            raise ImproperlyConfigured(

View on GitHub (pinned to ae25a40be0)

Solutions

  1. Install/rebuild Python with SQLite extension loading enabled (build CPython against a SQLite compiled without SQLITE_OMIT_LOAD_EXTENSION and without --disable-load-extension).
  2. Use a Python distribution known to enable it (python.org official builds) instead of a stripped system package.
  3. Switch the project to the PostGIS backend if rebuilding SQLite/Python is not feasible.
  4. If on macOS Homebrew Python, install pysqlite3 (pip install pysqlite3) and configure Django to use it, or rebuild Python via pyenv with the loadable-extension SQLite.

Example fix

// before: system python with load_extension disabled
DATABASES = {
  'default': {'ENGINE': 'django.contrib.gis.db.backends.spatialite', 'NAME': 'db.sqlite3'}
}
// after: rebuild CPython with extension loading, or switch engine
DATABASES = {
  'default': {'ENGINE': 'django.contrib.gis.db.backends.postgis', 'NAME': 'gisdb'}
}
Defensive patterns

Strategy: validation

Validate before calling

# run once during environment setup; fails fast before migrations
import sqlite3
conn = sqlite3.connect(':memory:')
if not hasattr(conn, 'enable_load_extension'):
    raise SystemExit('SQLite has no load_extension support; rebuild Python/SQLite')
conn.enable_load_extension(True)
print('OK: SQLite can load extensions')

Type guard

def sqlite_supports_extensions() -> bool:
    import sqlite3
    c = sqlite3.connect(':memory:')
    return hasattr(c, 'enable_load_extension')

Prevention

When it happens

Trigger: On every new SpatiaLite connection, get_new_connection() calls conn.enable_load_extension(True) at base.py:44; the AttributeError is caught at line 45 and re-raised as ImproperlyConfigured. Happens on the first query/migration that opens a DB connection when ENGINE is django.contrib.gis.db.backends.spatialite.

Common situations: Python built/installed without SQLITE_OMIT_LOAD_EXTENSION, or a distribution that ships pysqlite/sqlite3 with extension loading disabled for security (some Debian/macOS Homebrew with --disable-load-extension). Using the system python3-sqlite on a hardened OS; running in a sandbox that strips the extension API.

Related errors


AI-assisted analysis of django/django@ae25a40be0 (2026-08-06). Data as JSON: /api/errors/ff61cb186793bd61. Report an issue: GitHub.