
# Troubleshooting

The errors you are most likely to meet when you start Sovrium, what causes each
one, and how to fix it. Every entry quotes the **real message** Sovrium prints, so
you can match what you see in your terminal.

If you are stuck on a config, run `sovrium validate <config>` first — it checks your
file in isolation and prints exactly what is wrong.

## The server started on a different port

```text
[SERVER] Port 3000 in use; using an OS-assigned port (see URL below).
```

Another process already holds the port, so Sovrium boots on a free one instead
rather than failing. Read the URL printed in the startup output to find the real
address, or pick a free port yourself:

```bash
PORT=4000 sovrium start app.yaml
```

An out-of-range `PORT` is rejected outright:

```text
Error: Invalid port number "99999". Must be between 0 and 65535 (0 = auto-select).
```

## "Server already running"

```text
Error: Server already running (PID: 12345, port: 3000)
```

A Sovrium instance is already running (Sovrium tracks it with a lock file). Stop it
first:

```bash
sovrium stop
```

A stale lock left by a crashed process (its PID is no longer alive) is detected and
removed automatically, so this only blocks you when an instance really is running.

## "Unsupported DATABASE_URL scheme"

```text
Unsupported DATABASE_URL scheme: "./data/app.db". Use postgres://, postgresql://,
file:, sqlite:, or :memory:. A bare filesystem path is not accepted — prefix it
with file: (e.g. file:./database.db).
```

`DATABASE_URL` is set but is not a recognised scheme — a bare filesystem path is the
usual mistake. You have three good options:

- **Leave `DATABASE_URL` unset.** Sovrium then uses an embedded SQLite database with
  zero setup — this is the default and needs no database server.
- **Point at a SQLite file** by prefixing the path with `file:` — `file:./database.db`.
- **Use PostgreSQL** with a full URL — `postgres://user:password@localhost:5432/app`.

:::callout
**SQLite is the zero-config default.** With no `DATABASE_URL`, Sovrium stores data in
a local SQLite file — tables and authentication work out of the box, nothing to
install. Set `DATABASE_URL` only when you want to choose the file location or switch
to PostgreSQL. See [Database Infrastructure](/en/docs/database-infrastructure).
:::

## "Validation failed" (config errors)

`sovrium validate` — and every boot — checks your configuration against the schema.
On failure you get a tree of the exact problems under one header:

```text
Validation failed:
  <indented tree of the specific errors>
```

Two specifics you may see inside that tree:

- `Unknown field type "colour" in field "status"` — a table field uses a type that
  does not exist. See [Field Types Overview](/en/docs/field-types-overview) for the
  valid set.
- `Action "..." ... uses "type: cloud", which requires the Sovrium Cloud host gate
(SOVRIUM_CLOUD_MODE). This config is not running in cloud mode.` — a cloud-only
  action cannot run in the self-hosted binary.

A valid file prints `Valid configuration: <name>` and exits cleanly.

## "SOVRIUM_ENCRYPTION_KEY is required"

```text
SOVRIUM_ENCRYPTION_KEY is required. Generate a strong random value (e.g.
`openssl rand -base64 32`) and set it in the deployment environment, or set
SOVRIUM_ALLOW_DEV_KEY=1 to use the deterministic dev fallback for local
development only.
```

A feature that encrypts stored secrets — such as OAuth connection tokens — needs an
encryption key. Generate one and set it:

```bash
sovrium secret generate       # prints SOVRIUM_ENCRYPTION_KEY=<64-hex>
# or: openssl rand -base64 32
```

For local development only, you can skip key management with `SOVRIUM_ALLOW_DEV_KEY=1`,
which uses a deterministic throwaway key.

:::callout
**Never use the dev key in production.** `SOVRIUM_ALLOW_DEV_KEY` exists for local work.
A real deployment must set a strong, secret `SOVRIUM_ENCRYPTION_KEY`.
:::

## "File not found" or "No configuration provided"

```text
Error: File not found: app.yaml
```

The config path does not exist — check the filename and directory. Related messages:

- `Error: No configuration provided` — you ran a command with no config file and no
  `APP_SCHEMA`. Pass a file: `sovrium start app.yaml`.
- `Error: Unsupported file format: .toml` — Sovrium reads `.json`, `.yaml`, `.yml`,
  and `.ts`.

## "Failed to parse" your config

```text
Error: Failed to parse YAML file: app.yaml

Details: <the underlying parser error>
```

A syntax error in the file. The classic cause is **tabs in a YAML file** — YAML
indentation must use spaces, never tabs. Read the `Details:` line for the exact spot,
fix it, and re-run `sovrium validate app.yaml`. TypeScript configs report
`Failed to load TypeScript file` instead (a type or import error).

## Auth: "You are using the default secret"

```text
You are using the default secret. Please set `BETTER_AUTH_SECRET` in your
environment variables or pass `secret` in your auth config.
```

In production (`NODE_ENV=production`), an app with authentication needs a real secret.
In development it falls back to a built-in dev secret and only warns, so this appears
when you deploy. Generate one:

```bash
sovrium secret generate auth   # prints AUTH_SECRET=<64-hex>
```

:::callout
**The variable is `AUTH_SECRET`.** The underlying auth library's message names
`BETTER_AUTH_SECRET`, but Sovrium reads `AUTH_SECRET`. Set that one.
:::

## "Email sending disabled — SMTP not configured"

```text
Email sending disabled — SMTP not configured (set SMTP_HOST to enable)
```

This is a **warning, not a failure**. Your app can send email (email verification,
password reset, notification actions) but no SMTP server is configured, so email is
logged instead of sent — sign-up and reset links will not arrive. Set `SMTP_HOST` (and
the related `SMTP_*` variables) to enable delivery. See
[Environment Variables](/en/docs/env-vars).

## MCP: "no token is set"

```text
MCP env validation failed: MCP_AUTH_STRATEGY=token but no
MCP_TOKEN_ADMIN/MEMBER/VIEWER is set. At least one role token must be configured
for clients to authenticate.
```

You enabled the MCP server with token authentication but did not set a token. Provide
at least one role token (each must be 32 characters or longer):

```bash
MCP_TOKEN_ADMIN=$(openssl rand -hex 32)
```

See [MCP Integration](/en/docs/mcp-integration) for the full connection setup.

## Still stuck?

- Run `sovrium validate <config>` to check the configuration on its own.
- An uncaught failure prints `Unexpected error:` with a message and a link to open an
  issue — copy that message into your report.
- Search the docs with `⌘K`, or open a
  [GitHub issue](https://github.com/sovrium/sovrium/issues) or
  [discussion](https://github.com/sovrium/sovrium/discussions).

## Related Pages

- [Installation](/en/docs/installation) — install and first run.
- [Environment Variables](/en/docs/env-vars) — every variable Sovrium reads.
- [CLI Reference](/en/docs/cli) — commands, flags, and configuration sources.
- [Configuration Files](/en/docs/configuration-files) — YAML, JSON, and TypeScript.
