Skip to content
flexcal Documentation

Troubleshooting

Symptom. After deploying to a server or domain, login redirects and internal links go to http://localhost:3000 instead of your domain.

Cause. NEXT_PUBLIC_WEBAPP_URL (and optionally NEXTAUTH_URL) still hold the default value.

Fix.

NEXT_PUBLIC_WEBAPP_URL=https://cal.example.com
NEXTAUTH_URL=https://cal.example.com
  • No trailing slash.
  • NEXTAUTH_URL is optional when NEXT_PUBLIC_WEBAPP_URL is set: NextAuth infers the base URL from the request’s Host header.
  • NEXT_PUBLIC_WEBAPP_URL is inlined by Next.js at build time. For a self-built image, rebuild after changing it. The published image rewrites the placeholder on first container start, so setting the run-time variable is enough there.
  • On Vercel, NEXTAUTH_URL is inferred from VERCEL_URL and does not need to be set.

Symptom.

[next-auth][error][CLIENT_FETCH_ERROR]
request to http://<your-domain>/api/auth/session failed, reason: getaddrinfo ENOTFOUND

Cause. The container cannot resolve its own public hostname from inside the Docker network.

Fix. Point the hostname at the container itself:

docker-compose.yml
services:
flexcal:
extra_hosts:
- "cal.example.com:127.0.0.1"

This keeps NEXTAUTH_URL on the public URL, which OAuth callbacks require.

Setting NEXTAUTH_URL=http://localhost:3000/api/auth also silences the error, but breaks OAuth: Google and Microsoft would redirect users to localhost.

Symptom. Requests fail with certificate errors when flexcal sits behind a load balancer that terminates HTTPS.

Option 1 — proxy forwards plain HTTP internally (most common). Keep NEXTAUTH_URL on the public HTTPS URL and forward the standard headers:

proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Option 2 — internal self-signed certificates. Trust your internal CA:

NODE_EXTRA_CA_CERTS=/path/to/internal-ca.crt

Option 3 — last resort.

NODE_TLS_REJECT_UNAUTHORIZED=0

Cause. Usually migrations have not been applied, or a previous setup attempt left a partial row.

Fix.

  1. Apply migrations:

    Terminal window
    bun run --cwd packages/prisma db-deploy
  2. Confirm DATABASE_URL is correct and the database is reachable.

  3. Check the application logs for the Prisma error, which names the failing field or constraint.

The /auth/setup endpoint creates the first user with the ADMIN role and only runs while the User table is empty. Clear the table before retrying if an earlier attempt half-succeeded.

Invalid prisma.user.create() with empty metadata

Section titled “Invalid prisma.user.create() with empty metadata”

Some versions cannot create a user when metadata is empty. Use an empty JSON object {} instead. id auto-increments, so leave it blank.

Web push is not configured. Generate a key pair and set both halves:

Terminal window
npx web-push generate-vapid-keys
NEXT_PUBLIC_VAPID_PUBLIC_KEY=<public>
VAPID_PRIVATE_KEY=<private>

Prisma: The database schema is not empty (P3005)

Section titled “Prisma: The database schema is not empty (P3005)”

Prisma tracks applied migrations in a _prisma_migrations table. If that table disagrees with the database, it refuses to continue. Mark the already-applied migrations as resolved, one at a time:

Terminal window
bun run prisma migrate resolve --applied <migration_name>

See Database migrations for the development-side details.

Search the issue tracker first, then open a new issue with your deployment method, the relevant .env keys (values redacted) and the log output.