Troubleshooting
Start with the app's log. It's JSON, one event per line, and names the cause of most problems:
docker compose ps
docker compose logs --tail 100 appFor more detail, set LOG_LEVEL: debug under app.environment and run docker compose up -d. Set it back
afterwards.
The app refuses to start
The container exits right after starting, or keeps restarting. The log starts with:
Invalid environment:
MASTER_KEY: must decode to 32 bytes (openssl rand -base64 32)Each line names a variable and the rule it breaks. Values are never printed. Fix them in .env or the compose
file, then run docker compose up -d. The Configuration reference lists every rule.
Two mistakes cause most of these:
MASTER_KEYcopied with a missing character, or generated with something other thanopenssl rand -base64 32.PUBLIC_URLwithouthttp://orhttps://.
Migrations failed
The log shows migrations failed and the container exits before serving traffic. The error object in the same
line has the cause.
| Cause in the log | Fix |
|---|---|
function uuidv7() does not exist | Postgres is older than 18. Upgrade the server, or use the bundled Postgres 18. |
connection refused, ENOTFOUND or a timeout | The database isn't reachable. Check the host and port in DATABASE_URL, and see the note on localhost in Use an existing Postgres. |
password authentication failed | Wrong credentials in DATABASE_URL. Percent-encode special characters in the password. |
permission denied | Jangka's user doesn't own the database. See Create the database. |
If the cause isn't clear, or a migration failed after an upgrade, restore the backup you took before upgrading and start the previous version again. See Upgrading.
The setup token is not valid
The app prints a new setup token every time it starts until setup is complete, and the old one stops working. Read the latest one:
docker logs jangka 2>&1 | grep "SETUP TOKEN" | tail -n 1Sign-in doesn't stick, or saving fails with "Cross-origin request rejected"
Jangka only accepts changes from requests whose origin matches PUBLIC_URL, and marks the session cookie
Secure when PUBLIC_URL starts with https://. So when the browser's address differs from PUBLIC_URL, for
example a different host, port or scheme:
- every save, comment or sign-in is rejected with
Cross-origin request rejected, or - you sign in and land back on the sign-in page, because the browser won't keep a
Securecookie over plainhttp://.
Set PUBLIC_URL to exactly the address in the browser's address bar, without a trailing path, and run
docker compose up -d.
Locked out after turning on SSO
If the SSO provider is misconfigured or down and password login is off, nobody can sign in. Turn password login back on temporarily:
app:
environment:
FORCE_PASSWORD_LOGIN: "true"docker compose up -dSign in with an admin's email and password, such as the admin created by the setup wizard, and fix the provider
under Admin → Authentication. Then remove the variable and run docker compose up -d again. While it's set,
the app logs a warning on every start.
Assistant replies arrive all at once
The assistant streams replies over Server-Sent Events. If a reply appears in one piece after a long pause, a
reverse proxy between the browser and Jangka is buffering the response. With nginx, set proxy_buffering off
and raise proxy_read_timeout. See Reverse proxy & TLS.
Exports stay queued
Exports and diagram renders run in the worker. With APP_ROLE=api, a separate container with APP_ROLE=worker
must be running. Check it with docker compose ps and docker compose logs worker. See
Run a separate worker.
MASTER_KEY is lost
Documents, users and settings aren't encrypted with MASTER_KEY and stay readable. Only stored secrets are
lost: LLM API keys and OIDC client secrets. There's no way to recover them, so replace them:
-
Generate a new key and put it in
.env:terminalsh openssl rand -base64 32 -
Run
docker compose up -d. -
Under Admin → LLM providers, enter each provider's API key again.
-
Under Admin → Authentication, enter each SSO provider's client secret again.
If SSO was the only way to sign in, start with FORCE_PASSWORD_LOGIN set, as described in
Locked out after turning on SSO, and keep it set until step 4 is done.
Then store the new key somewhere safe. See Backups.