django/django · critical · NotImplementedError

subclasses of SessionBase must provide a create() method

Error message

subclasses of SessionBase must provide a create() method

What it means

`SessionBase.create()` at base.py:466-474 raises `NotImplementedError`. It is the contract method that allocates a brand-new session record with a unique key. The base class calls it from `cycle_key()` (base.py:431-440) and from `_get_session` paths when a new session must be materialized. Concrete backends (db, cache, file, signed_cookies) override it; a custom backend that omits it will fail the first time a session is created or cycled.

Source

Thrown at django/contrib/sessions/backends/base.py:472

    def exists(self, session_key):
        """
        Return True if the given session_key already exists.
        """
        raise NotImplementedError(
            "subclasses of SessionBase must provide an exists() method"
        )

    async def aexists(self, session_key):
        return await sync_to_async(self.exists)(session_key)

    def create(self):
        """
        Create a new session instance. Guaranteed to create a new object with
        a unique key and will have saved the result once (with empty data)
        before the method returns.
        """
        raise NotImplementedError(
            "subclasses of SessionBase must provide a create() method"
        )

    async def acreate(self):
        return await sync_to_async(self.create)()

    def save(self, must_create=False):
        """
        Save the session data. If 'must_create' is True, create a new session
        object (or raise CreateError). Otherwise, only update an existing
        object and don't create one (raise UpdateError if needed).
        """
        raise NotImplementedError(
            "subclasses of SessionBase must provide a save() method"
        )

    async def asave(self, must_create=False):
        return await sync_to_async(self.save)(must_create)

View on GitHub (pinned to b5388a3a80)

Solutions

  1. Implement `create(self)` on your SessionStore subclass: generate a unique key, persist empty data, and set `self._session_key`.
  2. Subclass a built-in backend and only override what you need.
  3. Use a supported third-party backend instead of writing one from scratch.

Example fix

// before
class SessionStore(SessionBase):
    def load(self): ...
// after
class SessionStore(SessionBase):
    def create(self):
        while True:
            self._session_key = self._get_new_session_key()
            try:
                self.save(must_create=True)
            except CreateError:
                continue
            break
Defensive patterns

Strategy: type-guard

Validate before calling

class SessionStore(SessionBase):
    def create(self):
        while True:
            self._session_key = self._get_new_session_key()
            try:
                self.save(must_create=True)
            except CreateError:
                continue
            break
# verify override:
assert SessionStore.create is not SessionBase.create

Type guard

def overrides_create(cls) -> bool:
    return getattr(cls, 'create') is not getattr(SessionBase, 'create')

Prevention

When it happens

Trigger: Subclassing `SessionBase`/`SessionStore` without overriding `create()`. The error fires on login (when a new session is created) or on `request.session.cycle_key()` (e.g. after privilege change).

Common situations: Custom session backend missing one of the four required methods; backend built for read-only use that never tested session creation; refactor that renamed `create` accidentally.

Related errors


AI-assisted analysis of django/django@b5388a3a80 (2026-08-10). Data as JSON: /api/errors/8406d114f2a491c2. Report an issue: GitHub.