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
- Set app.secret_key to a long random value: app.secret_key = os.environ['SECRET_KEY'] or os.urandom(32).
- Load SECRET_KEY from environment/secret store before app.run; fail startup loudly if it is missing.
- 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
- Set SECRET_KEY at app construction, sourced from env or a secret store.
- Fail fast at startup if SECRET_KEY is missing.
- In tests, always assign app.secret_key in the factory.
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
- Session backend did not open a session.
- Tag ' ' is already registered.
- A valid Flask application was not obtained from
- Allowed methods must be a list of strings, for example…
- Cookies are disabled. Create a client with…
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 methodsView on GitHub (pinned to 3596b1ab61)