Is your Express.js server not starting? Getting EADDRINUSE, "Cannot find module", or other errors when running npm start or node app.js?
This complete guide covers all common Express server startup issues and their solutions.
Error: listen EADDRINUSE: address already in use :::3000
at Server.setupListenHandle [as _listen2] (net.js:1318:16)
at listenInCluster (net.js:1366:12)
at Server.listen (net.js:1452:7)
events.js:292
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE :::3000
Error: Cannot find module 'express'
Require stack:
- /Users/username/project/app.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
at Function.Module._load (internal/modules/cjs/loader.js:725:27)
Error: Cannot find module './routes/users'
SyntaxError: Unexpected token '{'
at wrapSafe (internal/modules/cjs/loader.js:979:16)
at Module._compile (internal/modules/cjs/loader.js:1027:27)
SyntaxError: Unexpected identifier
at Object.compileFunction (node:vm:352:18)
Server listening on port 3000
/Users/username/project/app.js:42
const result = await db.query(sql);
^
UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 127.0.0.1:5432
(node:12345) UnhandledPromiseRejectionWarning: Unhandled promise rejection.
This error originated by throwing inside of an async function without a catch block
Follow these steps in order:
npm list expresslsof -i :3000 (Mac/Linux) or netstat -ano | findstr :3000 (Windows)node app.js (read error message carefully)node -v (should be 14.x or higher)rm -rf node_modules && npm installError Message: Error: listen EADDRINUSE :::3000
Cause: Another process is already using port 3000 (or your configured port)
Solution 1: Kill the Process Using the Port
# macOS/Linux - Find what's using port 3000 lsof -i :3000 # Kill the process (replace PID with actual process ID) kill -9 PID # Or kill all processes on port 3000 lsof -ti:3000 | xargs kill -9 # Windows - Find what's using port 3000 netstat -ano | findstr :3000 # Kill the process (replace PID) taskkill /PID PID /F
Solution 2: Use a Different Port
// In your Express app (app.js or server.js)
const express = require('express');
const app = express();
// Use environment variable with fallback
const PORT = process.env.PORT || 3001;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Solution 3: Create .env File
# Create .env file in project root
echo "PORT=3001" > .env
# Install dotenv
npm install dotenv
# Load in your app (at the very top of app.js)
require('dotenv').config();
const PORT = process.env.PORT || 3000;
app.listen() multiple times. Make sure you only have ONE app.listen() call in your entire codebase.
Error: Cannot find module 'express'
# Install Express npm install express # Verify it's in package.json cat package.json | grep express # Check if node_modules exists ls node_modules # If node_modules is missing or corrupted: rm -rf node_modules package-lock.json npm install
Error: Cannot find module './routes/users'
// Common causes and fixes:
// ❌ Wrong - file doesn't exist
const users = require('./routes/users');
// ✓ Check if file exists
// Make sure routes/users.js exists
// ❌ Wrong - incorrect path
const users = require('./users'); // but file is in routes/
// ✓ Correct - use proper relative path
const users = require('./routes/users');
// ❌ Wrong - case sensitivity (on Linux/macOS)
const users = require('./routes/Users'); // but file is users.js
// ✓ Correct - match exact case
const users = require('./routes/users');
Verify All Dependencies:
# Check for missing dependencies npm list # Install all dependencies from package.json npm install # Install specific missing package npm install package-name # Clear npm cache if issues persist npm cache clean --force rm -rf node_modules package-lock.json npm install
Common JavaScript Syntax Errors:
// ❌ Missing closing bracket
app.get('/users', (req, res) => {
res.json({ users: [] });
// Missing }
// ✓ Correct
app.get('/users', (req, res) => {
res.json({ users: [] });
});
// ❌ Missing semicolon or comma
const config = {
port: 3000
host: 'localhost' // Missing comma
}
// ✓ Correct
const config = {
port: 3000,
host: 'localhost'
};
// ❌ Using await without async
app.get('/data', (req, res) => {
const result = await fetchData(); // Error!
});
// ✓ Correct
app.get('/data', async (req, res) => {
const result = await fetchData();
res.json(result);
});
Check for Syntax Errors:
# Run your app directly to see errors node app.js # Use a linter npm install --save-dev eslint npx eslint app.js # For TypeScript npm install --save-dev typescript npx tsc --noEmit
If your Express server crashes immediately after starting, it's often due to database connection failures.
Add Proper Error Handling:
const express = require('express');
const app = express();
// ❌ Bad - No error handling
const db = require('./db');
db.connect(); // If this fails, server crashes
// ✓ Good - With error handling
const db = require('./db');
db.connect()
.then(() => {
console.log('Database connected');
startServer();
})
.catch(err => {
console.error('Database connection failed:', err);
process.exit(1); // Exit gracefully
});
function startServer() {
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
}
// Add global error handlers
process.on('uncaughtException', (err) => {
console.error('Uncaught Exception:', err);
process.exit(1);
});
process.on('unhandledRejection', (err) => {
console.error('Unhandled Promise Rejection:', err);
process.exit(1);
});
Make Database Optional for Development:
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
// Try to connect to database, but don't block server startup
if (process.env.DATABASE_URL) {
const db = require('./db');
db.connect()
.then(() => console.log('Database connected'))
.catch(err => console.error('Database connection failed:', err));
} else {
console.log('Running without database (development mode)');
}
// Start server regardless of database status
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Ensure .env is Loaded Correctly:
// ✓ Correct - Load dotenv FIRST, before anything else
require('dotenv').config();
const express = require('express');
const app = express();
// Now environment variables are available
const PORT = process.env.PORT || 3000;
const DB_URL = process.env.DATABASE_URL;
console.log('Port:', PORT); // Verify it's loaded
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Example .env file:
# .env file in project root PORT=3000 NODE_ENV=development DATABASE_URL=mongodb://localhost:27017/myapp JWT_SECRET=your-secret-key API_KEY=your-api-key # No quotes needed for values # No spaces around = sign
Verify .env is Not Ignored:
# Check if .env is in .gitignore (it should be) cat .gitignore | grep .env # Make sure .env file exists in project root ls -la | grep .env # If .env doesn't exist, create it cat > .env << EOF PORT=3000 NODE_ENV=development EOF
Enable Express Debug Mode:
# macOS/Linux - Show all Express internal logs DEBUG=express:* node app.js # Windows CMD set DEBUG=express:* && node app.js # Windows PowerShell $env:DEBUG="express:*"; node app.js # Show only router logs DEBUG=express:router node app.js # Show multiple debug namespaces DEBUG=express:*,myapp:* node app.js
Add Strategic Console Logs:
require('dotenv').config();
console.log('1. Environment loaded');
const express = require('express');
console.log('2. Express loaded');
const app = express();
console.log('3. Express app created');
const PORT = process.env.PORT || 3000;
console.log('4. Port set to:', PORT);
app.use(express.json());
console.log('5. Middleware configured');
app.get('/', (req, res) => {
console.log('6. Root route hit');
res.send('Hello World!');
});
app.listen(PORT, () => {
console.log('7. Server started successfully on port', PORT);
});
// If you don't see "7", the issue is before app.listen()
Use Node.js Inspector:
# Start with inspector node --inspect app.js # Or with breakpoint on first line node --inspect-brk app.js # Open Chrome and go to: chrome://inspect # Click "inspect" on your Node process # You can now set breakpoints and step through code
Verify Node.js Version:
# Check current Node.js version node -v # Express 4.x requires Node.js 0.10 or higher # Express 5.x (beta) requires Node.js 14.x or higher # If version is too old, update Node.js: # macOS (using Homebrew) brew upgrade node # Linux (using nvm) nvm install --lts nvm use --lts # Windows - Download from nodejs.org
Use .nvmrc for Version Consistency:
# Create .nvmrc file echo "18.17.0" > .nvmrc # Team members can then use: nvm use # This ensures everyone uses same Node version
Common causes:
--save-dev instead of --save// ✓ Correct production configuration
const PORT = process.env.PORT || 3000;
const HOST = process.env.HOST || '0.0.0.0'; // Listen on all interfaces
app.listen(PORT, HOST, () => {
console.log(`Server running on ${HOST}:${PORT}`);
console.log('Environment:', process.env.NODE_ENV);
});
Check your package.json scripts:
{
"scripts": {
"start": "node app.js",
// Or maybe:
"start": "node server.js",
// Or with nodemon:
"start": "nodemon app.js",
// Or with environment variable:
"start": "PORT=3000 node app.js"
}
}
If npm start works, check what command it actually runs and use that directly.
// Problematic middleware that might cause issues
const express = require('express');
const app = express();
// ❌ Bad - Synchronous middleware that throws
app.use((req, res, next) => {
const config = require('./config'); // If this fails, server won't start
next();
});
// ✓ Good - Wrapped in try-catch
app.use((req, res, next) => {
try {
const config = require('./config');
req.config = config;
next();
} catch (err) {
console.error('Config loading failed:', err);
next(err);
}
});
EXPRESS SERVER TROUBLESHOOTING CHEATSHEET
==========================================
Check if Express is installed:
npm list express
Install Express:
npm install express
Check for port conflicts:
macOS/Linux: lsof -i :3000
Windows: netstat -ano | findstr :3000
Kill process on port:
macOS/Linux: kill -9 [PID]
Windows: taskkill /PID [PID] /F
Clear and reinstall dependencies:
rm -rf node_modules package-lock.json
npm install
Debug mode:
DEBUG=express:* node app.js
Check Node.js version:
node -v
Run with inspector:
node --inspect app.js
Test minimal Express app:
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('OK'));
app.listen(3000, () => console.log('Running on 3000'));
Common fixes:
✓ Ensure dotenv is loaded first
✓ Check app.listen() is called only once
✓ Add error handlers for async code
✓ Verify all file paths are correct
✓ Make sure .env file exists
Debugging checklist:
Visit our Interactive Diagnostic Wizard for personalized help.