nodemon: Occasional "port already in use" error on macOS

  • nodemon -v: 1.14.12
  • node -v: 9.4.0
  • Operating system/terminal environment: macOS High Sierra / zsh
  • Command you ran:
$ concurrently -k "webpack -d --config ./webpack/config/webpack.dev.config.js --watch" "nodemon ./bin/app.bundle"

This was my first attempt to update the Webpack build and restart the server simultaneously using concurrently. I thought maybe concurrently was causing some issues, so I opted for the Nodemon Webpack Plugin instead, only to find I was getting the same issue.

Expected behaviour

Nodemon should kill the server clean every time it restarts, or when it exits.

Actual behaviour

I’m informed that my server’s port is already running when Nodemon starts it (“Port 8080 is already in use”), even after forcibly killing the server on that port using the process ID listened with lsof -i. When files change and Nodemon restarts, sometimes it actually listens on the port, but most of the time it just complains the port is already in use. A clean reboot of my system usually makes the problem go away temporarily.

Steps to reproduce

Unfortunately, an extremely tricky issue to reproduce, seeing there does not seem to be a clear case of when it happens or when it doesn’t. It happens randomly, very often but not frequently. Here is how my server is being set up, though:

const port = normalizePort(process.env.PORT || '8080');
app.set('port', port);

if (port) {
  const server = http.createServer(app);

  server.listen(port);
  server.on('error', onError);
  server.on('listening', onListening);

  process.on('uncaughtException', () => server.close());
  process.on('SIGTERM', () => server.close());
  process.on('exit', () => server.close());

  function onError(error) {
    if (error.syscall !== 'listen') {
      throw error;
    }

    const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port.toString()}`;

    switch (error.code) {
      case 'EACCES':
        console.error(`${bind} requires elevated privileges`);
        process.exit(1);
        break;
      case 'EADDRINUSE':
        console.error(`${bind} is already in use`);
        process.exit(1);
        break;
      default:
        throw error;
    }
  }

  function onListening() {
    const addr = server.address();
    const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`;
    debug(`Listening on ${bind}`);
    console.log(`Server started on ${bind}`);
  }
}

function normalizePort(val) {
  const port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

If applicable, please append the --dump flag on your command and include the output here ensuring to remove any sensitive/personal details or tokens.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 12
  • Comments: 41 (13 by maintainers)

Most upvoted comments

Was having the same issue, I too am using concurrently. Adding a delay of 2 seconds (nodemon --delay 2) seems to resolve this issues for me.

Hey al - @remy ,

Node v8.3.0 nodemon v1.17.2 Mac OS X 10.12.6

I’m having the same issue and it also seems to be isolated to one particular project. I’ll run nodemon index.js and will receive a Error: listen EADDRINUSE :::5000after having saved changes to a file, and never after manually issuing rs.

I will lsof -i tcp:5000 and kill the PID but the issue always recurs. I also had Concurrently running in this application, however the issue persists when starting app using only the Nodemon command. Could past use of the Concurrently module still be affecting Nodemon’s management of processes???

screen shot 2018-03-28 at 1 46 34 pm

prior to updating nodemon from 1.12.1 to 1.17.2:

screen shot 2018-03-28 at 1 28 18 pm

I was experiencing this situation as well and I could not replicate it at all outside of one single project. it wound up being a rogue nodemon process that was competing with my primary nodemon process. It seemed to flip between each of these processes to determine which one “won” and which one received the port in use error, which is why the issue seemed to occur somewhat randomly. I suspect that this process came into existence with a layered npm script like ‘concurrently’. Either way, when I removed the competing process, the issue resolved and I haven’t seen it since.

Killing the process is not an ideal solution. If I have to list the system PID and kill it every time I save an ExpressJS file, I am screwed.

I’m using ExpressJS, nodemon and concurrently. After removing concurrently from the node stack, ExpressJS is loading up ok, 60-70% of the time it manages to end the process before restarting again (nodemon).

@anhtran304 ,

You could also kill your server like so: lsof -i tcp:PORT_NUMBER // List network process on PORT_NUMBER, i.e. 5000 get the PID number and then: kill -9 PID_NUMBER //Kill your server

It’s probably better than killing node itself.

I’m having the same issue, I’m just using express. The reason seems to be about concurrency, when doing watch -n 0.1 pgrep node -a is possible to see in a fraction of time, 3 running nodes (before reducing to just 1 node), and then the EADDRINUSE error. Running nodemon with --delay 0.5 is sufficiently to fix the problem…

Fedora 28 / kernel release 4.13.9-300.fc27.x86_64 Nodemon 1.17.5 Node v8.11.3 Express 4.16.3

Hi, I’m on a Mac and am also getting this issue even when using nodemon directly.

It looks like it’s nodemon is not working as expected with the signal SIGINT

I’ve added the following to my Koa app to work around the issue, will work with others as well:

process.on(‘SIGINT’, () => { console.log(‘do SIGINT’); process.exit(); });

Had similar problem, appeared inconsistently.

Nodemon was indeed starting and ending server process, but is was doing it simultaneously and old server process was still listening to port 5000, when new server tried to listen to it.

Adding 2s delay by adding nodemon.json in project root fixed it in my case.

{
    "delay": "2000"
}

But i still wonder how can i make it wait exactly enough for old process to release port, or force it to end old and start new sequentially. Maybe there should be some sort of switch that toggles this behaviour?

nodemon -v 6.14.10 node v14.15.3 Linux Mint 20

Excellent. Some progress finally. Without checking concurrently’s source, I’m going to guess they’re trapping the SIGUSR2 that’s being sent.

If you try your original nodemon setup, but pass it a flag of --signal SIGINT - can you replicate the issue?

I was using dotenv library for environment variables and I encountered the same problem. For me it was ‘.env’ file.

It was like: PORT=3000,

Don’t forget to remove commas if you are copy pasting from json.