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.
- Confirm
OAUTH_GROUPS_CLAIMandOAUTH_ROLE_MAPare set in the container:docker compose exec app env | grep OAUTH. - Confirm the
profilescope is enabled on the provider sogroupsis emitted. - Confirm the group names in
OAUTH_ROLE_MAPmatch Authentik exactly. - 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.