Skip to content

app.listen() error behavior is different in Express 4 vs. 5, if port is occupied #6191

@heidemn-faro

Description

@heidemn-faro

Hi there,
Great to see that Express 5 with async request handlers is finally available :-)

I have a question about behavior that differs in Express 4 vs. 5, if the listen port is already in use.
I wanted to know if that's on purpose, or if it's a bug.
If it's on purpose, it should probably be mentioned here? https://expressjs.com/en/guide/migrating-5.html
Thanks for having a look!

// minimal-express.mjs

import express from 'express';
import expressPkg from 'express/package.json' with { type: "json" };

const app = express();
app.use(express.json());
app.get('/api/health', (req, res) => {
	res.status(200).json({ status: 'ok' });
});

console.log('Express ', expressPkg.version);
console.log('Starting Express server on port 7072...');
const server = app.listen(7072, '0.0.0.0', () => {
	console.log('Callback');
	if (!server.address()) {
		// This line is only reachable in Express 5, but not in Express 4.
		throw new Error('Failed to start server (Express 5).');
	}
	console.log('Listening on http://localhost:7072/ - e.g. http://localhost:7072/api/health');
});

Enviroment: WSL2, Ubuntu 22.04, Node 20 or 22

PRETTY_NAME="Ubuntu 22.04.5 LTS"
Linux MYHOSTNAME 5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Node.js v20.18.1
Node.js v22.11.0 (same result)

Results with Express 4, if port is already in use:

Express  4.21.1
Starting Express server on port 7072...
node:events:497
      throw er; // Unhandled 'error' event
      ^

Error: listen EADDRINUSE: address already in use 0.0.0.0:7072
    at Server.setupListenHandle [as _listen2] (node:net:1904:16)
    at listenInCluster (node:net:1961:12)
    at doListen (node:net:2135:7)
    at process.processTicksAndRejections (node:internal/process/task_queues:83:21)
Emitted 'error' event on Server instance at:
    at emitErrorNT (node:net:1940:8)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  code: 'EADDRINUSE',
  errno: -98,
  syscall: 'listen',
  address: '0.0.0.0',
  port: 7072
}

Results with Express 5, if port is already in use:

Express  5.0.1
Starting Express server on port 7072...
Callback
file:///some/folder/minimal-express.mjs:14
                throw new Error('Failed to start server (Express 5).');
                ^

Error: Failed to start server (Express 5).
    at Server.<anonymous> (file:///some/folder/minimal-express.mjs:14:9)
    at Server.f (/some/folder/node_modules/once/once.js:25:25)
    at Object.onceWrapper (node:events:634:26)
    at Server.emit (node:events:519:28)
    at emitErrorNT (node:net:1940:8)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

Metadata

Metadata

Assignees

Labels

docsDocumentations issues

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions