# How to Troubleshoot Open-Notebook: FastAPI, SurrealDB, and Frontend Diagnostics

> Troubleshoot Open Notebook issues by checking container logs, verifying environment variables, and confirming database migrations. Resolve FastAPI, SurrealDB, and frontend problems efficiently.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: how-to-guide
- Published: 2026-06-08

---

**TLDR:** Open Notebook is a three-tier application (frontend → FastAPI → SurrealDB), and nearly every failure can be isolated by checking container logs, verifying environment variables like `OPEN_NOTEBOOK_ENCRYPTION_KEY` and `CORS_ORIGINS`, and confirming that database migrations completed successfully.

Troubleshooting `lfnovo/open-notebook` starts with its architecture. The stack runs as three distinct layers—frontend interface, FastAPI backend, and SurrealDB datastore—so every symptom points to a specific tier. By tracing failures through the source code paths below, you can diagnose and resolve most issues without guessing.

## Troubleshoot Open-Notebook API Startup and Migration Failures

When the API container launches, the `lifespan` handler in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) (lines 98–127) orchestrates startup. It first validates that `OPEN_NOTEBOOK_ENCRYPTION_KEY` is defined, logging a critical warning if the variable is missing. Then it delegates to `AsyncMigrationManager` from [`open_notebook/database/async_migrate.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/database/async_migrate.py) to run pending SurrealDB migrations; if these fail, the service aborts entirely.

The most common startup symptom is a log line reading **"CRITICAL: Database migration failed"**. To fix this, inspect the container output with `docker logs open_notebook` and verify that SurrealDB is reachable on port `8000` via `telnet <host> 8000`. If the database version has drifted, run `docker exec -it surrealdb /surreal version` and compare it with the API log entry showing `Current database version:`.

A missing encryption key triggers subtle failures later. You must export a secret before starting the stack, as shown in the sample [`docker-compose.yml`](https://github.com/lfnovo/open-notebook/blob/main/docker-compose.yml) (lines 31–33) and the [`README.md`](https://github.com/lfnovo/open-notebook/blob/main/README.md) (lines 44–49):

```bash
export OPEN_NOTEBOOK_ENCRYPTION_KEY=$(openssl rand -hex 32)

```

If migrations are stuck in an inconsistent state, delete the `surreal_data` Docker volume and restart the compose stack so SurrealDB initializes a fresh datastore.

## Fix CORS Misconfiguration in Open-Notebook

The API parses `CORS_ORIGINS` at startup inside [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) (lines 53–64). If the variable is absent, the backend defaults to `*` and logs a warning, which causes browsers to reject cross-origin requests whenever credentials are sent.

Symptoms include a blank UI and **"Failed to fetch"** errors in the browser console. Inspect the response headers with a quick `curl` command:

```bash
curl -I http://localhost:5055/api/health

```

If `Access-Control-Allow-Origin` is missing or set to `*` while your frontend sends cookies, explicitly set the exact frontend URL in your environment:

```dotenv
CORS_ORIGINS=https://localhost:8502

```

After updating `.env` or [`docker-compose.yml`](https://github.com/lfnovo/open-notebook/blob/main/docker-compose.yml), restart the API container so the new CORS policy takes effect.

## Resolve Authentication and Encryption Key Errors in Open-Notebook

`PasswordAuthMiddleware` protects all routes except an explicit whitelist, as configured in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) (lines 73–86). This middleware relies on the same `OPEN_NOTEBOOK_ENCRYPTION_KEY` used during startup; if the key is absent or differs between containers, every protected endpoint returns **401 Unauthorized**.

Symptoms include repeated login loops and a **"Login required"** overlay even after entering valid credentials. Ensure the secret is identical in both the API container and the frontend runtime, because the frontend retrieves it from `/api/config` to validate password hashes. Any mismatch prevents decryption and blocks access.

## Handle Podcast Profile Migration Warnings

During startup, a legacy migration routine runs inside [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) (lines 39–46). Errors here are logged but **do not stop** the service, so you may see warnings such as "Podcast profile migration encountered errors" while the API remains online.

If old profile strings were not converted automatically, open the notebook UI and navigate to **Settings → Podcast Profiles**, then click **Migrate Profiles**. The UI invokes the migration endpoint again and completes the conversion interactively.

## Diagnose Open-Notebook Frontend Connection Errors

The UI surfaces generic failures through [`ConnectionErrorOverlay.tsx`](https://github.com/lfnovo/open-notebook/blob/main/ConnectionErrorOverlay.tsx) (line 59), pulling text from the locale file [`frontend/src/lib/locales/en-US/index.ts`](https://github.com/lfnovo/open-notebook/blob/main/frontend/src/lib/locales/en-US/index.ts) (line 174). This overlay usually appears when the frontend cannot reach the API, but the root cause can sit at multiple network layers.

- **API URL mismatch.** The frontend base URL is defined in `.env.local` and expects the API at `http://localhost:5055` by default. If you changed ports or hostnames, propagate that value into the build.

- **Reverse-proxy header stripping.** If you run nginx or Traefik in front of the stack, confirm it forwards the `Host` and `Origin` headers and preserves CORS headers on error responses. The project documentation in [`docs/5-CONFIGURATION/reverse-proxy.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/5-CONFIGURATION/reverse-proxy.md) covers recommended proxy settings.

- **Docker network isolation.** Run `docker network inspect <network>` and verify that both the `open_notebook` and `surrealdb` services attach to the same bridge.

Run these quick tests from the host and from inside the frontend container:

```bash

# From the host

curl http://localhost:5055/api/health

# From inside the frontend container

docker exec -it open_notebook_frontend curl http://open_notebook:5055/api/health

```

Both calls must return `{"status":"healthy"}`.

## Fix AI Provider and Model Timeouts in Open-Notebook

Open Notebook uses the Esperanto library for multi-provider AI. Provider-specific failures surface as `ExternalServiceError`, handled in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) (lines 71–78). You will typically see **"No models available"** or **"Failed to send message"** in the chat UI.

Start by verifying the credential record exists through [`api/routers/credentials.py`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/credentials.py). In the UI, go to **Settings → API Keys → Test Connection** to confirm the key is active. If the request times out, test outbound network access from the container:

```bash
docker exec open_notebook ping api.openai.com

```

For local Ollama deployments, ensure the model name matches the output of `ollama list` exactly, as noted in [`CHANGELOG.md`](https://github.com/lfnovo/open-notebook/blob/main/CHANGELOG.md) (lines 260–261). If you are using the Google provider and Docker cannot resolve the host, add `extra_hosts` to your compose service as described in [`docs/5-CONFIGURATION/ollama.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/5-CONFIGURATION/ollama.md) (line 330).

## Quick Diagnostic Scripts for Open-Notebook

The repository ships a rapid troubleshooting guide in [`docs/6-TROUBLESHOOTING/quick-fixes.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/6-TROUBLESHOOTING/quick-fixes.md). Use the following scripts to automate common checks.

### Bash health-check script

Save the following to [`health_check.sh`](https://github.com/lfnovo/open-notebook/blob/main/health_check.sh) and run it to verify API and database reachability:

```bash
#!/usr/bin/env bash
set -e

if curl -sSf http://localhost:5055/api/health | grep -q "healthy"; then
  echo "✅ API healthy"
else
  echo "❌ API not responding"
  exit 1
fi

if nc -zv localhost 8000 2>/dev/null; then
  echo "✅ SurrealDB reachable"
else
  echo "❌ SurrealDB not reachable"
fi

```

### Inspect CORS headers with Python

Use this snippet to read the `Access-Control-Allow-Origin` header returned by the API:

```python
import requests

resp = requests.get("http://localhost:5055/api/health")
print("CORS header:", resp.headers.get("Access-Control-Allow-Origin"))

```

### Trigger a migration manually

If the API fails to start because of a migration error, you can run the manager directly:

```python
import asyncio
from open_notebook.database.async_migrate import AsyncMigrationManager

async def run():
    mgr = AsyncMigrationManager()
    await mgr.run_migration_up()
    print("Migrations applied")

asyncio.run(run())

```

### Test AI credentials via cURL

Send a direct request to the credentials router to validate an API key:

```bash
curl -X POST http://localhost:5055/api/credentials/test \
  -H "Content-Type: application/json" \
  -d '{"provider":"openai","api_key":"sk-..."}'

```

A successful response contains `"status":"ok"`.

## Summary

- **Check container logs first.** Run `docker logs open_notebook` and `docker compose ps` to confirm every service is healthy.
- **Validate environment variables.** `OPEN_NOTEBOOK_ENCRYPTION_KEY` and `CORS_ORIGINS` are the most common sources of silent failures and 401 errors.
- **Confirm database reachability.** Use `telnet` or `nc` against SurrealDB port `8000`, and match the reported database version with the API logs.
- **Inspect CORS headers.** Browsers block requests when `Access-Control-Allow-Origin` is `*` while credentials are enabled.
- **Test AI providers from the UI.** Use **Settings → API Keys → Test Connection** before assuming a model outage.
- **Delete and recreate the `surreal_data` volume** only when migrations are irreparably stuck, since this wipes the datastore.

## Frequently Asked Questions

### Why does the Open Notebook API container exit immediately on startup?

The `lifespan` handler in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) (lines 98–127) aborts the process when `AsyncMigrationManager` cannot apply pending SurrealDB migrations. Check `docker logs open_notebook` for the exact migration error, verify SurrealDB is reachable on port `8000`, and ensure `OPEN_NOTEBOOK_ENCRYPTION_KEY` is exported in your environment.

### Why am I getting 401 Unauthorized even after logging in?

`PasswordAuthMiddleware`—configured in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) (lines 73–86)—requires the exact same `OPEN_NOTEBOOK_ENCRYPTION_KEY` on both the API and frontend to decrypt password hashes. If the keys differ, every protected route returns 401. Synchronize the secret across both containers and restart them.

### Why does the frontend show a "Connection error" overlay?

The overlay defined in [`frontend/src/components/errors/ConnectionErrorOverlay.tsx`](https://github.com/lfnovo/open-notebook/blob/main/frontend/src/components/errors/ConnectionErrorOverlay.tsx) (line 59) appears when the UI cannot fetch from the API. Confirm the frontend is pointing to the correct API URL, run `curl http://localhost:5055/api/health` from both the host and inside the frontend container, and verify that any reverse proxy preserves `Host` and `Origin` headers.

### How do I fix AI provider errors like "No models available"?

These are thrown as `ExternalServiceError` in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) (lines 71–78). Verify your provider credentials in [`api/routers/credentials.py`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/credentials.py), run the test connection button in **Settings → API Keys**, and check container outbound access with `docker exec open_notebook ping api.openai.com`. For Ollama users, confirm the model name matches `ollama list` exactly, and for Google provider timeouts add `extra_hosts` as documented in [`docs/5-CONFIGURATION/ollama.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/5-CONFIGURATION/ollama.md) (line 330).