How It Works Features Pricing Blog Error Guides
Log In Start Free Trial
Flask · Python

Fix RuntimeError: The session is unavailable because no secret key was set in Flask

This error occurs when Flask tries to use the session but no SECRET_KEY is configured. Flask uses the secret key to cryptographically sign session cookies. Fix it by setting app.config['SECRET_KEY'] to a strong random value, ideally loaded from an environment variable rather than hardcoded in source code.

Reading the Stack Trace

Traceback (most recent call last): File "/app/venv/lib/python3.12/site-packages/flask/app.py", line 869, in full_dispatch_request rv = self.dispatch_request() File "/app/app/routes.py", line 8, in login session['user_id'] = user.id File "/app/venv/lib/python3.12/site-packages/flask/sessions.py", line 127, in _get_session raise RuntimeError( File "/app/venv/lib/python3.12/site-packages/flask/sessions.py", line 100, in open_session raise RuntimeError( RuntimeError: The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.

Here's what each line means:

Common Causes

1. SECRET_KEY not set in config

The application was created without setting a SECRET_KEY, so Flask cannot sign session cookies.

app = Flask(__name__)
# no app.config['SECRET_KEY'] = ...

@app.route('/login', methods=['POST'])
def login():
    session['user_id'] = 1  # crashes

2. Environment variable missing

The config reads SECRET_KEY from an environment variable that is not set in the deployment environment.

app.config['SECRET_KEY'] = os.environ['SECRET_KEY']  # KeyError if not set

3. Secret key set after session access

The secret key is configured after the session is already accessed during request handling.

@app.before_request
def setup():
    session['visits'] = session.get('visits', 0) + 1  # too early

app.config['SECRET_KEY'] = 'my-secret'  # too late

The Fix

Set SECRET_KEY early in the application configuration, ideally from an environment variable. The fallback value is for local development only. In production, always set the SECRET_KEY environment variable to a strong random string.

Before (broken)
app = Flask(__name__)

@app.route('/login', methods=['POST'])
def login():
    session['user_id'] = user.id
    return redirect(url_for('dashboard'))
After (fixed)
import os

app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'dev-fallback-key-change-in-production')

@app.route('/login', methods=['POST'])
def login():
    session['user_id'] = user.id
    return redirect(url_for('dashboard'))

Testing the Fix

import pytest
from app import create_app

@pytest.fixture
def client():
    app = create_app()
    app.config['TESTING'] = True
    app.config['SECRET_KEY'] = 'test-secret-key'
    return app.test_client()

def test_session_works_after_login(client):
    response = client.post('/login', json={'email': 'test@example.com', 'password': 'password'})
    assert response.status_code in (200, 302)

def test_session_persists_across_requests(client):
    with client.session_transaction() as sess:
        sess['user_id'] = 1
    response = client.get('/dashboard')
    assert response.status_code == 200

def test_secret_key_is_set(client):
    assert client.application.config['SECRET_KEY'] is not None
    assert len(client.application.config['SECRET_KEY']) > 0

Run your tests:

pytest tests/ -v

Pushing Through CI/CD

git checkout -b fix/flask-session-secret-key,git add app/__init__.py,git commit -m "fix: set SECRET_KEY from environment for session support",git push origin fix/flask-session-secret-key

Your CI config should look something like this:

name: CI
on:
  pull_request:
    branches: [main]
jobs:
  test:
    runs-on: ubuntu-latest
    env:
      SECRET_KEY: ci-test-secret-key
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: 'pip'
      - run: pip install -r requirements.txt
      - run: pytest tests/ -v --tb=short
      - run: flake8 app/

The Full Manual Process: 18 Steps

Here's every step you just went through to fix this one bug:

  1. Notice the error alert or see it in your monitoring tool
  2. Open the error dashboard and read the stack trace
  3. Identify the file and line number from the stack trace
  4. Open your IDE and navigate to the file
  5. Read the surrounding code to understand context
  6. Reproduce the error locally
  7. Identify the root cause
  8. Write the fix
  9. Run the test suite locally
  10. Fix any failing tests
  11. Write new tests covering the edge case
  12. Run the full test suite again
  13. Create a new git branch
  14. Commit and push your changes
  15. Open a pull request
  16. Wait for code review
  17. Merge and deploy to production
  18. Monitor production to confirm the error is resolved

Total time: 30-60 minutes. For one bug.

Or Let bugstack Fix It in Under 2 minutes

Every step above? bugstack does it automatically.

Step 1: Install the SDK

pip install bugstack

Step 2: Initialize

import bugstack

bugstack.init(api_key=os.environ["BUGSTACK_API_KEY"])

Step 3: There is no step 3.

bugstack handles everything from here:

  1. Captures the stack trace and request context
  2. Pulls the relevant source files from your GitHub repo
  3. Analyzes the error and understands the code context
  4. Generates a minimal, verified fix
  5. Runs your existing test suite
  6. Pushes through your CI/CD pipeline
  7. Deploys to production (or opens a PR for review)

Time from error to fix deployed: Under 2 minutes.

Human involvement: zero.

Try bugstack Free →

No credit card. 5-minute setup. Cancel anytime.

Deploying the Fix (Manual Path)

  1. Run pytest locally to confirm sessions work with the secret key set.
  2. Open a pull request with the configuration change.
  3. Wait for CI checks to pass on the PR.
  4. Have a teammate review and approve the PR.
  5. Merge to main, set the SECRET_KEY environment variable in production, and verify sessions work in staging.

Frequently Asked Questions

BugStack verifies the secret key is loaded from environment variables, tests session creation and persistence, and runs your suite to confirm no regressions before marking it safe.

BugStack never pushes directly to production. Every fix goes through a pull request with full CI checks, so your team can review it before merging.

Run python -c "import secrets; print(secrets.token_hex(32))" to generate a cryptographically secure 64-character hex string.

Yes. All existing session cookies become invalid when you change the secret key, logging out all active users. Plan accordingly.