You hit Ctrl+C, restart your server, and Node refuses to boot: the port is still held by a zombie process. Here is how to free it and prevent the next one.
The Error
Error: listen EADDRINUSE: address already in use :::3000
Fix 1: Find and Kill the Process
# macOS / Linux
lsof -i :3000 # find the PID using the port
kill -9 <PID> # force-kill it
# One-liner
kill -9 $(lsof -t -i:3000)
# Windows
netstat -ano | findstr :3000
taskkill /PID <PID> /FFix 2: Use an Environment-Driven Port
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Listening on ${PORT}`));Fix 3: Shut Down Gracefully
Zombie ports usually mean the old process never released the socket. Close the server on termination signals:
const server = app.listen(PORT);
process.on("SIGINT", () => {
server.close(() => process.exit(0));
});
process.on("SIGTERM", () => {
server.close(() => process.exit(0));
});Using nodemon?
A crash loop can leave orphaned processes. Add a small restart delay and ensure your shutdown handlers run so the socket is released before the next boot.
