Troubleshooting
This guide covers the most common problems encountered when installing and operating ElyOS.
Application Won’t Start
Section titled “Application Won’t Start”Missing Required Environment Variables
Section titled “Missing Required Environment Variables”Symptom: Application crashes on startup with missing configuration error.
Cause: DATABASE_URL, BETTER_AUTH_SECRET, or BETTER_AUTH_URL not set.
Solution: Ensure .env file contains at least:
DATABASE_URL=postgresql://elyos:elyos123@localhost:5432/elyosBETTER_AUTH_SECRET=<generate: openssl rand -base64 32>BETTER_AUTH_URL=http://localhost:3000Port Already in Use
Section titled “Port Already in Use”Symptom: Error: listen EADDRINUSE :::3000
Cause: Another process is already using port 3000 (or configured port).
Solution: Stop the conflicting process or change the port:
ELYOS_PORT=3001NODE_ENV Not Set
Section titled “NODE_ENV Not Set”Symptom: Unexpected behavior, missing features, or insecure defaults.
Cause: If NODE_ENV is not set, the application runs in development mode. In production, this causes performance and security issues.
Solution: Always set in production: NODE_ENV=production.
Database Problems
Section titled “Database Problems”Cannot Connect to PostgreSQL
Section titled “Cannot Connect to PostgreSQL”Symptom: Connection refused or ECONNREFUSED error on startup.
Cause: Host/port in DATABASE_URL is unreachable.
Common mistakes:
- Using
localhostas host inside Docker (use service name:postgres) - Wrong port (default:
5432) - PostgreSQL container not ready when app tries to connect
Solution (local):
DATABASE_URL=postgresql://elyos:elyos123@localhost:5432/elyosSolution (Docker Compose): Don’t set DATABASE_URL in .env — Docker Compose automatically builds it from POSTGRES_* variables using internal postgres hostname.
Authentication Error
Section titled “Authentication Error”Symptom: password authentication failed for user "elyos"
Cause: POSTGRES_USER / POSTGRES_PASSWORD in .env don’t match database initialization values.
Solution: Ensure POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB match values used when volume was first created. If changed after creation, delete volume and restart:
docker compose -f docker/docker-compose.yml down -vdocker compose -f docker/docker-compose.yml up -dMigrations Not Run / Missing Tables
Section titled “Migrations Not Run / Missing Tables”Symptom: relation "..." does not exist errors.
Cause: Database never initialized or migrations didn’t run.
Solution (Docker): db-init service runs automatically on first startup. If it failed, check logs:
docker logs elyos-db-initSolution (local):
bun db:initAuthentication Issues
Section titled “Authentication Issues”BETTER_AUTH_SECRET Still Has Default Placeholder
Section titled “BETTER_AUTH_SECRET Still Has Default Placeholder”Symptom: Sessions insecure or auth tokens invalid after deployment.
Cause: BETTER_AUTH_SECRET value is your-secret-here or change-me-in-production.
Solution: Generate proper secret before first startup:
openssl rand -base64 32BETTER_AUTH_URL Doesn’t Match APP_URL
Section titled “BETTER_AUTH_URL Doesn’t Match APP_URL”Symptom: OAuth callbacks fail, email verification links are wrong, or users redirected to wrong URL.
Cause: BETTER_AUTH_URL must exactly match application’s public URL.
Solution: Both values must be identical:
APP_URL=https://elyos.example.comBETTER_AUTH_URL=https://elyos.example.comGoogle Sign-In Not Working
Section titled “Google Sign-In Not Working”Symptom: Google sign-in button missing or returns error.
Cause: SOCIAL_LOGIN_ENABLED is false, or GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET not set.
Solution:
SOCIAL_LOGIN_ENABLED=trueGOOGLE_CLIENT_ID=your-client-idGOOGLE_CLIENT_SECRET=your-client-secretAlso ensure OAuth redirect URI is set in Google Cloud Console: <APP_URL>/api/auth/callback/google.
Registration Disabled But No Admin User Exists
Section titled “Registration Disabled But No Admin User Exists”Symptom: Nobody can log in and no account creation option.
Cause: REGISTRATION_ENABLED=false set before first admin user created.
Solution: Temporarily enable registration, create admin account, then disable again. Or set ADMIN_USER_EMAIL before running bun db:init:
ADMIN_USER_EMAIL=admin@example.comEmail Issues
Section titled “Email Issues”Emails Not Arriving
Section titled “Emails Not Arriving”Symptom: Verification emails, OTP codes, or password reset emails never arrive.
Cause: Email provider not properly configured, or EMAIL_TEST_MODE=true (emails only logged to console).
Solution: First check EMAIL_TEST_MODE:
EMAIL_TEST_MODE=falseThen verify provider-specific variables match selected EMAIL_PROVIDER.
SMTP Authentication Error
Section titled “SMTP Authentication Error”Symptom: 535 Authentication failed or similar SMTP error in logs.
Cause: Wrong SMTP_USERNAME / SMTP_PASSWORD, or SMTP server requires app-specific password (e.g., Gmail).
Solution: For Gmail, generate App Password and use as SMTP_PASSWORD. Requires two-factor authentication enabled on Google account.
Wrong SMTP Port / TLS Mismatch
Section titled “Wrong SMTP Port / TLS Mismatch”Symptom: Connection timeout or TLS handshake error.
Cause: SMTP_PORT and SMTP_SECURE values don’t match.
Solution:
| Port | SMTP_SECURE | Protocol |
|---|---|---|
| 587 | false | STARTTLS |
| 465 | true | SSL/TLS |
| 25 | false | Plain |
Translation Keys Showing Instead of Text
Section titled “Translation Keys Showing Instead of Text”Symptom: Raw translation keys appear instead of text — e.g., auth.login.title instead of “Login”.
Cause 1: Missing ORIGIN → 403 errors on translation fetch
Translation loader makes server calls on startup. If ORIGIN not set correctly, these calls return 403 Forbidden and UI shows raw keys.
Solution: Set ORIGIN to exact public URL:
ORIGIN=https://elyos.example.comCheck browser Network tab — if translation requests return 403, this is the cause.
Cause 2: Missing translations in database
Translations stored in platform.translations table. If database not seeded or seed incomplete, table is empty and no text loads.
Solution: Run seed to populate translations:
# Localbun db:seed
# Or full resetbun db:initDocker case, restart with volume deletion:
docker compose -f docker/docker-compose.yml down -vdocker compose -f docker/docker-compose.yml up -dCheck table directly:
SELECT COUNT(*) FROM platform.translations;If result is 0, seed didn’t run.
403 Error on Remote Calls
Section titled “403 Error on Remote Calls”Symptom: Server actions (form submissions, data modifications) return 403 Forbidden.
Cause: ORIGIN variable not set or doesn’t match URL application is accessed from. SvelteKit CSRF protection rejects requests where Origin header doesn’t match.
Solution: Set ORIGIN to exact public URL:
ORIGIN=https://elyos.example.comMust match URL in browser address bar — including protocol and port if non-standard.
Docker Issues
Section titled “Docker Issues”Container Keeps Restarting
Section titled “Container Keeps Restarting”Symptom: docker logs elyos-app shows repeated startup errors.
Cause: Usually missing environment variable, failed database connection, or db-init service didn’t complete.
Solution:
- Check
db-initlogs:docker logs elyos-db-init - Check app logs:
docker logs elyos-app - Ensure all required variables set in
.env
Uploaded Files Disappear After Container Restart
Section titled “Uploaded Files Disappear After Container Restart”Symptom: Uploaded files disappear when container restarts.
Cause: apps/web/uploads directory not mounted as volume.
Solution: Default docker-compose.yml already includes ../apps/web/uploads:/app/uploads volume mount. If using custom config, ensure this mount exists.
Port Conflict with PostgreSQL
Section titled “Port Conflict with PostgreSQL”Symptom: bind: address already in use on port 5432.
Cause: Local PostgreSQL instance already running on host.
Solution: Change host-side port mapping:
POSTGRES_PORT=5433Plugin System Issues
Section titled “Plugin System Issues”Plugin Upload Fails with Size Limit Error
Section titled “Plugin Upload Fails with Size Limit Error”Symptom: Plugin upload rejected with size limit error.
Cause: Plugin package exceeds PLUGIN_MAX_SIZE (default: 10 MB).
Solution: Increase limit (max 100 MB):
PLUGIN_MAX_SIZE=52428800 # 50 MBPlugin Storage Directory Not Writable
Section titled “Plugin Storage Directory Not Writable”Symptom: Plugin installation fails with permission error.
Cause: Process doesn’t have write permission to PLUGIN_STORAGE_DIR or PLUGIN_TEMP_DIR.
Solution: Ensure directories exist and are writable:
mkdir -p /var/webos/plugins /tmp/webos-pluginschmod 755 /var/webos/pluginsLogging and Diagnostics
Section titled “Logging and Diagnostics”No Log Output
Section titled “No Log Output”Symptom: Application runs but produces no log output.
Cause: LOG_LEVEL set too high (e.g., fatal), or LOG_TARGETS doesn’t include console.
Solution:
LOG_TARGETS=consoleLOG_LEVEL=infoLog Files Not Written
Section titled “Log Files Not Written”Symptom: LOG_TARGETS=file set but no files appear in LOG_DIR.
Cause: Log directory doesn’t exist or not writable.
Solution: Create directory and ensure it’s writable:
mkdir -p ./logsOr set custom path:
LOG_DIR=/var/log/elyosEnable Detailed Logging for Debugging
Section titled “Enable Detailed Logging for Debugging”For maximum verbosity during troubleshooting:
LOG_TARGETS=console,fileLOG_LEVEL=debugLOG_DIR=./logs