Troubleshooting Guide
This page covers 20+ common issues organized by category, with symptoms, root causes, and actionable fixes.
Setup Issuesβ
1. Port 4005 already in useβ
Symptom: Error: listen EADDRINUSE: address already in use :::4005 when starting the backend.
Cause: Another process (or a previous crashed instance) is still bound to port 4005.
Fix:
# Find the process using port 4005
lsof -i :4005
# Kill it
kill -9 <PID>
# Or use a one-liner
kill -9 $(lsof -t -i :4005) 2>/dev/null; cd backend && npm run dev
If you need to change the port, set PORT=4006 in your backend/.env file.
2. Database connection refusedβ
Symptom: Error: connect ECONNREFUSED 127.0.0.1:5432 or Connection to server at "localhost" refused.
Cause: PostgreSQL Docker container is not running.
Fix:
# Start only PostgreSQL (never run full docker-compose up locally)
docker-compose up -d postgres
# Verify it's running
docker-compose ps
# Test connection
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard -c "SELECT 1"
If the container keeps crashing, check logs:
docker-compose logs postgres
Common sub-causes:
- Docker Desktop not running (start Docker Desktop first)
- Port 5432 used by a host-installed PostgreSQL (stop it:
brew services stop postgresql) - Volume corruption (remove and recreate:
docker-compose down -v && docker-compose up -d postgres)
3. npm install fails with node-gyp errorsβ
Symptom: Build errors mentioning node-gyp, bcrypt, or native module compilation failures.
Cause: Missing build tools or Node.js version mismatch.
Fix:
# Ensure you're on Node.js 18+
node --version
# If using nvm
nvm use 18
# Clean install
cd backend && rm -rf node_modules package-lock.json && npm install
cd ../frontend && rm -rf node_modules package-lock.json && npm install
On macOS, ensure Xcode command line tools are installed:
xcode-select --install
4. Environment variables not loadingβ
Symptom: Tenable Access Key is required or JWT secret must be at least 32 characters errors on startup.
Cause: Missing or malformed backend/.env file.
Fix:
# Check if .env exists
ls -la backend/.env
# Copy from template if missing
cp backend/.env.example backend/.env
# Verify critical variables are set
grep -E "^(JWT_SECRET|DB_PASSWORD|TENABLE_ACCESS_KEY)" backend/.env
Required variables (from backend/src/config/env.ts):
JWT_SECRET-- at least 32 charactersDB_PASSWORD-- database passwordTENABLE_ACCESS_KEY-- Tenable.io API access keyTENABLE_SECRET_KEY-- Tenable.io API secret keyDATABASE_URL-- full PostgreSQL connection string
5. Frontend shows blank white pageβ
Symptom: http://localhost:3005 shows a blank page with no errors in the browser console.
Cause: Usually a Vite dev server issue or missing environment variables.
Fix:
# Restart the frontend dev server
cd frontend && npm run dev
# If that fails, clean and rebuild
cd frontend && rm -rf node_modules/.vite && npm run dev
Check the browser console for CORS errors -- if the backend URL is wrong, API calls will fail silently. Verify VITE_API_BASE_URL in frontend/.env points to http://localhost:4005/api.
Scanning Issues (AppSec Module)β
6. Assessment stuck in 'queued' statusβ
Symptom: The assessment shows "Queued" in the UI and never progresses.
Cause: The PentestCoordinator has not picked up the assessment. This can happen if:
- The backend was restarted while a scan was queued
- The assessment's target URL fails outbound validation
Fix:
# Check backend logs for errors
cd backend && npm run dev # Watch the console output
# Verify the target URL is reachable from the backend
curl -I <target-url>
If the assessment is stuck, you can reset it via the database:
-- Connect to the database
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard
-- Reset assessment status
UPDATE pentest_assessments SET status = 'queued', started_at = NULL WHERE id = '<assessment-id>';
7. Zero findings after a scanβ
Symptom: Scan completes but shows 0 findings.
Cause: Multiple possible causes:
- Authentication failure: Test users could not log in to the target
- No endpoints discovered: Crawling found no API endpoints
- Target unreachable: Network connectivity issues between backend and target
- All agents skipped: Budget exhausted before agents could run
Fix:
Check the agent logs in the database:
SELECT agent_name, status, requests_sent, findings_created, error_message
FROM pentest_agent_logs
WHERE assessment_id = '<assessment-id>'
ORDER BY started_at;
Check Phase 0 authentication:
SELECT scan_context->'testUsers' FROM pentest_assessments WHERE id = '<assessment-id>';
Verify the target is accessible from the backend host (especially in Docker/cloud environments where network rules may block outbound traffic).
8. Agent not connecting to targetβ
Symptom: Agent logs show ECONNREFUSED or ENOTFOUND errors.
Cause: The target URL is unreachable from the backend server.
Fix:
# Test connectivity from the backend host
curl -v <target-url>
# If running in Docker, test from inside the container
docker-compose exec backend curl -v <target-url>
For local targets (e.g., http://localhost:8080), use your machine's IP address or host.docker.internal instead of localhost if the backend runs in Docker.
Authentication Issuesβ
9. JWT expired / 401 on every requestβ
Symptom: All API calls return 401 Unauthorized with code INVALID_TOKEN or TOKEN_EXPIRED.
Cause: The access token has expired (default 15-minute lifetime) and the refresh flow failed.
Fix:
- Try refreshing:
POST /api/auth/refresh(the frontend does this automatically) - If refresh also fails, log in again
- Check that
JWT_SECRETin.envhas not changed since the token was issued -- changing the secret invalidates all existing tokens
# Quick test: log in and get a fresh token
curl -X POST http://localhost:4005/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@company.com","password":"Admin123@same!"}'
10. SSO redirect loopβ
Symptom: Clicking "Sign in with Microsoft" endlessly redirects between ThreatWeaver and Microsoft.
Cause: SSO callback URL mismatch or state parameter corruption.
Fix:
- Verify the redirect URI in Azure AD app registration matches exactly:
https://<backend-url>/api/sso/callback - Check that
SSO_REDIRECT_URIin.envmatches the Azure AD registered redirect URI - Ensure cookies are not being blocked (SameSite policy issues)
- Check the backend logs for specific OAuth2 errors
11. CORS errors in browser consoleβ
Symptom: Access to XMLHttpRequest has been blocked by CORS policy in the browser console.
Cause: The frontend origin is not in the backend's CORS allowlist.
Fix:
Set CORS_ORIGIN in backend/.env to match your frontend URL:
# For local development
CORS_ORIGIN=http://localhost:3005
# For UAT
CORS_ORIGIN=https://dev.threatweaver.ai
# For production (set this when production hosting is confirmed)
# CORS_ORIGIN=https://threatweaver.ai
If you need multiple origins, separate them with commas. Restart the backend after changing .env.
Database Issuesβ
12. Migration failedβ
Symptom: npm run migrate:local fails with SQL errors.
Cause: Schema conflict, missing column, or duplicate migration.
Fix:
# Check migration status
cd backend && npm run migrate:status
# Reset local database (WARNING: destroys all data)
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard \
-c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
# Re-run migration
cd backend && npm run migrate:local
If the migration partially applied, you may need to manually fix the schema:
# Connect to the database
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard
# Check what tables exist
\dt
# Check specific table columns
\d+ users
13. Tenant schema not foundβ
Symptom: 503 Database schema not available or Error: Schema "tenant_xxx" does not exist.
Cause: In multi-tenant mode, the tenant schema has not been provisioned.
Fix:
For local development, ensure DEPLOYMENT_MODE is not set (single-tenant mode uses the public schema):
# Remove or comment out in backend/.env
# DEPLOYMENT_MODE=saas
If you need multi-tenant mode locally, provision the schema:
CREATE SCHEMA IF NOT EXISTS "tenant_mycompany";
Then run migrations targeting that schema.
14. Connection pool exhaustedβ
Symptom: Error: Cannot acquire connection from pool or requests hanging/timing out.
Cause: Too many open connections, usually from unreleased QueryRunners.
Fix:
# Check active connections
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard \
-c "SELECT count(*) FROM pg_stat_activity WHERE datname = 'tenable_dashboard';"
# Kill idle connections
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard \
-c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'tenable_dashboard' AND state = 'idle' AND pid <> pg_backend_pid();"
If this recurs, look for code paths that create a QueryRunner but do not release it. The setTenantSchema middleware handles this automatically via res.on('finish') and res.on('close') cleanup hooks.
15. TypeORM "relation does not exist" errorβ
Symptom: QueryFailedError: relation "some_table" does not exist
Cause: The entity is defined but the table was never created (migration was not run).
Fix:
# Run local migrations (includes synchronize for development)
cd backend && npm run migrate:local
# Verify the table exists
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard -c "\dt some_table"
In multi-tenant mode, make sure you are querying the correct schema. Use getTenantAwareRepository() instead of AppDataSource.getRepository().
Frontend Issuesβ
16. Page not loading after adding a new routeβ
Symptom: Navigating to a new page shows a blank area or 404-like behavior.
Cause: Missing one of the three required routing pieces.
Fix: Verify all three exist:
- Sidebar href in
frontend/src/components/Sidebar.tsx--href: '/my-page' - Route definition in
frontend/src/App.tsx--<Route path="/my-page" ... /> - Component import -- the page component is correctly imported
All three path values must match exactly.
17. API calls returning 401 in the frontendβ
Symptom: Pages load but data does not appear; network tab shows 401 responses.
Cause: The auth cookie is not being sent with requests.
Fix:
- Check that the API client includes
credentials: 'include'in fetch/axios config - Verify that
CORS_ORIGINon the backend matches the exact frontend URL (including protocol and port) - Check that cookies are not blocked by browser privacy settings
- Try logging in again -- the token may have expired
18. Frontend build fails with TypeScript errorsβ
Symptom: npm run build in the frontend fails with type errors.
Fix:
cd frontend
# Check for type errors
npx tsc --noEmit
# If it's a dependency issue, clean and reinstall
rm -rf node_modules && npm install
# Build
npm run build
Common causes:
- Missing type definitions (install
@types/...packages) - Stale
tsconfig.tsbuildinfo(delete it:rm tsconfig.tsbuildinfo) - Import path mismatches (check
.tsvs.tsxextensions)
19. Backend build fails for Render deploymentβ
Symptom: npm run build (tsc) succeeds locally but fails on Render.
Cause: Common Render-specific issues:
Fix:
- Never add
"type": "module"to backendpackage.json - Keep
tsxindevDependencies(notdependencies) - Test the build locally before pushing:
cd backend && rm -rf dist && npm run build && npm start
- Check that all imports use
.jsextensions (TypeScript ESM resolution) - Verify
tsconfig.jsonhas"outDir": "dist"and"module": "NodeNext"
20. Vite HMR not working (changes not reflecting)β
Symptom: Code changes in the frontend are not reflected in the browser.
Fix:
# Clear Vite cache
cd frontend && rm -rf node_modules/.vite
# Restart dev server
npm run dev
If HMR is still broken:
- Check that the file is being saved (auto-save may be disabled)
- Check the terminal for Vite compilation errors
- Try a hard refresh in the browser (Cmd+Shift+R / Ctrl+Shift+R)
Performance Issuesβ
21. Aggregation queries slow (dashboard loading slowly)β
Symptom: Dashboard takes 10+ seconds to load.
Cause: The aggregation.service.ts runs complex queries over large vulnerability datasets without cached results.
Fix:
- Check if the cache is working: the service caches KPI results
- Check database indexes:
-- Verify indexes exist on commonly queried columns
\d+ vulnerabilities
- Check the vulnerability count -- if there are 100,000+ records, consider archiving old data via
POST /api/admin/archive
22. Memory usage growing over timeβ
Symptom: Backend Node.js process memory increases steadily.
Cause: Possible causes include:
- In-memory caches not expiring (user cache, token revocation cache)
- Large scan results held in memory
Fix:
# Check Node.js memory usage
node -e "console.log(process.memoryUsage())"
# Set max memory for Node.js
NODE_OPTIONS="--max-old-space-size=2048" npm run dev
The auth middleware caches are bounded:
- User cache: 30-second TTL per entry
- Revoked token cache: 5,000 max entries with 60-second cleanup
Quick Diagnostic Commandsβ
# Check if backend is running
curl http://localhost:4005/api/health
# Check database connectivity
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard -c "SELECT 1"
# Check backend logs (if running with npm run dev)
# Logs appear in the terminal where you started the backend
# Check frontend is accessible
curl http://localhost:3005
# Verify login works
curl -X POST http://localhost:4005/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@company.com","password":"Admin123@same!"}'
# Check sync status
curl http://localhost:4005/api/sync/status \
-H "Cookie: token=<your-jwt-token>"
# Database shell
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard