Skip to main content

Troubleshooting

The app exits on start​

The app validates its environment on start; a missing declared variable aborts startup with a list. Ensure every variable from src/env.ts is present — the image defaults cover all of them, so this usually means you overrode one with an empty value.

Cross-site POST form submissions are forbidden (403)​

Rare: SvelteKit's origin check is disabled by default (csrf.trustedOrigins: ['*']). If it reappears, the request Origin doesn't match the origin derived from Host. Forward the original Host and X-Forwarded-Proto from the proxy, or pin ORIGIN:

PUBLIC_ORIGIN=https://intranet.example docker compose up -d --force-recreate app worker

Everyone signs in as engineer​

The groups claim isn't reaching the app, or the groups aren't mapped.

  1. Confirm OAUTH_GROUPS_CLAIM and OAUTH_ROLE_MAP are set in the container: docker compose exec app env | grep OAUTH.
  2. Confirm the profile scope is enabled on the provider so groups is emitted.
  3. Confirm the group names in OAUTH_ROLE_MAP match Authentik exactly.
  4. Sign out and back in — the role re-syncs on each login.

invalid_redirect_uri​

The redirect URI registered with the provider doesn't exactly match <origin>/api/auth/callback/<OAUTH_PROVIDER_ID>. The origin is derived from the request, so register the browser origin — or set ORIGIN to pin it. Scheme, host, port, and path must all match. Update the provider if the origin changed.

Login succeeds at the provider but returns "not authorized"​

The user's Authentik group isn't bound to the application. Add a binding.

Discovery fetch fails / provider missing​

The container can't reach the provider. Test from inside:

docker compose exec app node -e "fetch(process.env.OAUTH_DISCOVERY_URL).then(r=>console.log(r.status)).catch(console.error)"

A common cause is a hostname that resolves only on the host (a LAN IP or localhost). Use an address the container resolves, or add an entry to the service's extra_hosts.

Seed fails with Cannot find file .env​

The image runs touch .env so node --env-file=.env resolves. If you built a custom image, ensure that step or set DATABASE_URL in the environment.

Port already in use​

Change APP_PORT/POSTGRES_PORT in .env, or stop the conflicting service.

Database connection refused​

Confirm db is healthy (docker compose ps), DATABASE_URL is correct, and — when using an external database — that the host is reachable and allows the container's address.

Collecting diagnostics​

docker compose ps
docker compose logs --tail=200 app worker migrate
docker compose exec app env | grep -E 'APP_ENV|ORIGIN|OAUTH'

Never paste BETTER_AUTH_SECRET, OAUTH_CLIENT_SECRET, or DATABASE_URL credentials unredacted.