Troubleshooting
Common self-host failures: database URL, migrations, DSN, CORS, sessions.
What usually fails on a self-host?
A wrong database URL, a session cookie Secure mismatch, a missing CORS origin, or a revoked DSN key. Start with the matrix.
| Symptom | Likely cause | Fix |
|---|---|---|
up cannot pull ghcr.io/epure-sh/epure | Package missing or private | Wait for a tagged Image workflow; set the GHCR package to public. Contributors: docker compose -f docker-compose.yml -f docker-compose.build.yml up --build |
| App exits on start / migrate errors | Wrong DATABASE_URL or Postgres not ready | Match compose credentials; wait for postgres healthy; check docker compose logs epure |
| Connection refused on the old port | EPURE_PORT changed, or .env not picked up | Curl EPURE_PUBLIC_URL/health; recreate epure after .env edits |
| Boot refuses example DB passwords | EPURE_PUBLIC_URL is not localhost, or leftover CHANGE_ME | Use .env.production.example; set the three role passwords |
EPURE_PUBLIC_URL must be https:// | Production config without TLS origin | Set https://your-host; put Caddy/nginx in front |
EPURE_CORS_ORIGINS must list real origins | * in production | List frontend origins comma-separated |
cargo test / host tools cannot connect | Using port 5432 on host | Dev compose maps Postgres to 5433 (POSTGRES_HOST_PORT) |
| Login loops after HTTPS deploy | Insecure cookie on HTTPS or secure cookie on HTTP | Prod: EPURE_SESSION_SECURE=1 + TLS in front. Local HTTP: 0 |
| Google button missing | GOOGLE_CLIENT_ID empty | Set Google env vars; restart epure |
| OAuth redirect error | Redirect URI mismatch | GOOGLE_REDIRECT_URI = {EPURE_PUBLIC_URL}/api/v1/auth/google/callback |
| Browser SDK CORS failure | Origin not allowed | Set EPURE_CORS_ORIGINS to your frontend origins (comma-separated) |
| Ingest 403 | Bad or revoked DSN | Create/rotate key; update SDK; revoked keys are rejected |
| Ingest 202 but no issue | Worker lag or processing error | Wait ~500 ms; docker compose logs epure |
| Events dropped under load | Ingest cap or spike valve | Check project ingest cap (default 5000/hr); spike valve increments counters while discarding bodies |
| Webhook never arrives | Private URL / SSRF guard | Use public HTTPS; do not set EPURE_WEBHOOK_ALLOW_PRIVATE=1 in prod |
| Disk growth | Retention / partitions | Lower retention (14/30/90); TTL drops old events_YYYY_MM partitions daily |
| Stack still minified | Maps missing or wrong release | Upload JS/TS maps to the matching release version (Releases) |
Which database URL should I use?
Inside the epure container, Postgres is postgres:5432. On the host against default compose, use 5433 (POSTGRES_HOST_PORT in .env).
Compose (inside the epure container):
postgres://epure:epure@postgres:5432/epureHost tools against default compose:
postgres://epure:epure@localhost:5433/epureAlso set when running outside Compose:
EPURE_INGEST_DATABASE_URL=postgres://epure_ingest:epure_ingest@localhost:5433/epureEPURE_APP_DATABASE_URL=postgres://epure_app:epure_app@localhost:5433/epure
The prod overlay publishes no Postgres port; reach it with docker compose exec postgres psql -U epure -d epure.
When do migrations run?
Migrations apply on Epure startup, never as a manual job. Failures show up in docker compose logs epure.
Fix connectivity or credentials, then recreate the app container. After a failed upgrade migration, restore the pre-upgrade dump before retrying a new image.
How do I test DSN ingest?
POST envelope or store with X-Sentry-Auth. Expect 202 and { "id": "<uuid>" }; the body cap is 2 MB.
Interactive builder: Quickstart · Try ingest.
curl -sS -w "\nHTTP %{http_code}\n" \
-X POST "http://localhost:8080/api/${PROJECT_ID}/envelope/" \
-H "Content-Type: application/x-sentry-envelope" \
-H "X-Sentry-Auth: Sentry sentry_version=7, sentry_key=${PUBLIC}, sentry_secret=${SECRET}" \
--data-binary @fixtures/sentry/browser/envelope.txtHow do I debug CORS?
Browser SDKs need a successful OPTIONS preflight on envelope and store. Expect 200 or 204 with Access-Control-Allow-Origin.
curl -sS -D - -o /dev/null -X OPTIONS \
"http://localhost:8080/api/${PROJECT_ID}/envelope/" \
-H "Origin: http://localhost:5173" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: X-Sentry-Auth, Content-Type"Why does my session drop?
Login succeeds, then /api/v1/* acts logged out. The browser is rejecting the cookie over a Secure flag mismatch.
| Deploy | EPURE_SESSION_SECURE | Cookie |
|---|---|---|
| Local HTTP | 0 | Epure.sid |
| HTTPS | 1 | __Host-epure.sid (Secure only) |
How do I get more signal?
Follow the logs, raise the log level, then check container state and health. Recreate epure after any env change.
docker compose logs -f Epure
RUST_LOG=debug # temporary: set in compose/env, then recreate
docker compose ps
curl -sS http://localhost:8080/healthFAQ
Why does the app exit on migrate?
Wrong DATABASE_URL, or Postgres is not ready. Wait for postgres to report healthy and read docker compose logs epure. Host tools must use port 5433, and epure needs a recreate after credentials change. Copy URLs from Configuration.
Why is ingest 403?
The DSN public key is missing, wrong, or revoked, or the URL project id does not match the key. Copy a new key from Settings → SDK connection. Revoked keys return dsn_revoked and mismatched project ids return project_mismatch. The hourly cap returns ingest_cap_exceeded: Verify.
Why 202 with no issue?
Accept is non-blocking, so wait about a second. Match the environment chip to the SDK tag and confirm the project that owns the DSN. Then read docker compose logs epure. Spike-valve floods still return 202 while dropping bodies: Verify.
Why does login loop after HTTPS?
Cookie Secure flag mismatch. The production overlay sets EPURE_SESSION_SECURE=1 and needs TLS in front; local HTTP needs 0. Google OAuth also needs GOOGLE_REDIRECT_URI equal to {EPURE_PUBLIC_URL}/api/v1/auth/google/callback. Restart epure after env changes.
Why are events dropped under load?
The hourly project cap (default 5000) returns 403 ingest_cap_exceeded. The spike valve (~100/min/fingerprint) still returns 202 and bumps counters while dropping bodies. Raise the cap in project settings, or slow the flood. Codes: API errors.