pallets/flask · error · RuntimeError

The session is unavailable because no secret key was set. …

Error message

The session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.

What it means

When app.secret_key is not set, Flask's SecureCookieSessionInterface uses NullSession, whose mutating methods (__setitem__, clear, pop, update, etc.) all call _fail and raise RuntimeError. Sessions need the secret key to sign cookies; without it, write attempts are rejected. Read access to the empty session still works.

Solutions

  1. Set app.secret_key to a long random value: app.secret_key = os.environ['SECRET_KEY'] or os.urandom(32).
  2. Load SECRET_KEY from environment/secret store before app.run; fail startup loudly if it is missing.
  3. For tests, set app.secret_key = 'test' in the test app factory.

Example fix

// before
app = Flask(__name__)
@app.route('/')
def index():
    session['k'] = 1  # raises
    return 'ok'

// after
app = Flask(__name__)
app.secret_key = os.environ['SECRET_KEY']
@app.route('/')
def index():
    session['k'] = 1
    return 'ok'
Defensive patterns

Strategy: validation

Validate before calling

def require_secret_key(app):
    if not app.secret_key:
        raise RuntimeError('app.secret_key is not set; session writes will fail')

Type guard

def app_has_secret_key(app) -> bool:
    return bool(getattr(app, 'secret_key', None))

Try / catch

try:
    session['k'] = value
except RuntimeError as e:
    if 'session is unavailable' in str(e).lower():
        # set secret_key before serving; do not ignore
        raise

Prevention

When it happens

Trigger: Writing to flask.session (session['user']=x) before setting app.secret_key; running a dev server with FLASK_DEBUG but no SECRET_KEY in config; tests that mutate session on a freshly created app without a key.

Common situations: Missing SECRET_KEY env var; config loading order putting secret_key assignment after the first request; switching from server-side sessions to default cookie sessions without setting a key; tutorial code that omitted the key.

Related errors


AI-assisted analysis of pallets/flask@3596b1ab61 (2026-08-11). Data as JSON: /api/errors/bc586ed409dd403c. Report an issue: GitHub.

Appendix: source

Thrown at src/flask/sessions.py:90

    def __init__(
        self,
        initial: c.Mapping[str, t.Any] | None = None,
    ) -> None:
        def on_update(self: te.Self) -> None:
            self.modified = True

        super().__init__(initial, on_update)


class NullSession(SecureCookieSession):
    """Class used to generate nicer error messages if sessions are not
    available.  Will still allow read-only access to the empty session
    but fail on setting.
    """

    def _fail(self, *args: t.Any, **kwargs: t.Any) -> t.NoReturn:
        raise RuntimeError(
            "The session is unavailable because no secret "
            "key was set.  Set the secret_key on the "
            "application to something unique and secret."
        )

    __setitem__ = __delitem__ = clear = pop = popitem = update = setdefault = _fail
    del _fail


class SessionInterface:
    """The basic interface you have to implement in order to replace the
    default session interface which uses werkzeug's securecookie
    implementation.  The only methods you have to implement are
    :meth:`open_session` and :meth:`save_session`, the others have
    useful defaults which you don't need to change.

    The session object returned by the :meth:`open_session` method has to
    provide a dictionary like interface plus the properties and methods

View on GitHub (pinned to 3596b1ab61)