jngkadocs
Operations / Troubleshooting

Troubleshooting

Start with the app's log. It's JSON, one event per line, and names the cause of most problems:

terminalsh
docker compose ps
docker compose logs --tail 100 app

For 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_KEY copied with a missing character, or generated with something other than openssl rand -base64 32.
  • PUBLIC_URL without http:// or https://.

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 logFix
function uuidv7() does not existPostgres is older than 18. Upgrade the server, or use the bundled Postgres 18.
connection refused, ENOTFOUND or a timeoutThe 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 failedWrong credentials in DATABASE_URL. Percent-encode special characters in the password.
permission deniedJangka'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:

terminalsh
docker logs jangka 2>&1 | grep "SETUP TOKEN" | tail -n 1

Sign-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 Secure cookie over plain http://.

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:

docker-compose.ymlyaml
  app:
    environment:
      FORCE_PASSWORD_LOGIN: "true"
terminalsh
docker compose up -d

Sign 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:

  1. Generate a new key and put it in .env:

    terminalsh
    openssl rand -base64 32
  2. Run docker compose up -d.

  3. Under Admin → LLM providers, enter each provider's API key again.

  4. 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.