How to fix Error: Primary cluster worker is not listening (listening server required) in Node.js
This error occurs when worker processes in a Node.js cluster module are trying to emit 'listening' events but no actual listening server exists in the worker processes. The cluster module expects workers to have a net.Server instance listening on a port to handle incoming connections.
Quick fix
Fixes ERR_CLUSTER_LISTENING_ERROR
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isPrimary) {
// PRIMARY: Fork workers, don't listen
console.log('Primary process starting...');
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log('Worker died, restarting...');
cluster.fork();
});
} else {
// WORKER: Create and listen on server
const server = http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello from worker ' + process.pid);
});
server.listen(8000, () => {
console.log('Worker listening on port 8000');
});
}- Verify the cluster.isPrimary conditional is correct
- Ensure workers create a net.Server or http.Server instance
- If using non-server services, remove cluster.on('listening')
- Test with a minimal working example
const cluster = require('cluster');const http = require('http');const numCPUs = require('os').cpus().length;if (cluster.isPrimary) {// PRIMARY: Fork workers, don't listenconsole.log('Primary process starting...');for (let i = 0; i < numCPUs; i++) {cluster.fork();}cluster.on('exit', (worker, code, signal) => {console.log('Worker died, restarting...');cluster.fork();});} else {// WORKER: Create and listen on serverconst server = http.createServer((req, res) => {res.writeHead(200);res.end('Hello from worker ' + process.pid);});server.listen(8000, () => {console.log('Worker listening on port 8000');});}Error: Primary cluster worker is not listening (listening server required)
What this error means
The Node.js cluster module is designed to distribute incoming connections across multiple worker processes. When a worker calls `.listen()` on a server object (like an HTTP server), it signals to the cluster module that it has a listening server ready to accept connections. If you see this error, it means your code structure is incorrect. The cluster module expects: 1. Workers to have actual net.Server or http.Server instances calling `.listen(port)` 2. The primary process to fork workers (not listen itself) The error typically indicates that either: - Worker processes do not call .listen() on any server instance - The primary process is attempting to listen when it should only fork workers - You're using cluster with a non-network service (message queue consumer) that doesn't create listening servers
Typical symptoms
- Error thrown immediately when starting the application with cluster enabled
- Workers fail to initialize with cluster-related listening errors
- Application crashes before being able to accept HTTP/TCP connections
- Error appears in logs when cluster.on('listening') is used but no worker server is listening
- Works fine without the cluster module but fails when cluster module is enabled
Common causes
- Worker processes do not call .listen() on an http.Server or net.Server instance
- Attempting to use the cluster module with non-network-based services (message queues, background jobs) that don't create listening servers
- Primary process is attempting to listen() when it should only fork workers and let workers listen
- Using cluster with a custom server type that doesn't inherit from net.Server
- Incorrect cluster.isPrimary conditional logic that prevents workers from creating and listening on servers
How to fix "Error: Primary cluster worker is not listening (listening server required)"
The primary process should fork workers, while workers should create and listen on servers. Check that your code follows this pattern:
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isPrimary) {
// PRIMARY: Fork workers, don't listen
console.log('Primary process starting...');
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log('Worker died, restarting...');
cluster.fork();
});
} else {
// WORKER: Create and listen on server
const server = http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello from worker ' + process.pid);
});
server.listen(8000, () => {
console.log('Worker listening on port 8000');
});
}The key rule: only workers should call .listen() on servers, not the primary.
The cluster module specifically requires that workers have an actual listening server. Generic event emitters or message queue consumers without a listening server won't work.
Valid server types:
- http.createServer() - HTTP server
- https.createServer() - HTTPS server
- net.createServer() - Raw TCP server
Invalid patterns (will cause this error):
// WRONG: No server listening in workers
if (!cluster.isPrimary) {
const consumer = createRabbitMQConsumer(); // Not a listening server
consumer.on('message', handler);
// Error: No listening server, cluster.on('listening') never fires
}
// WRONG: Primary listening instead of workers
if (cluster.isPrimary) {
const server = http.createServer(...);
server.listen(8000); // Should be in worker block
cluster.fork();
}
// CORRECT: Workers have listening servers
if (!cluster.isPrimary) {
const server = http.createServer(...);
server.listen(8000); // Workers listen, primary doesn't
}If you need clustering for background job workers or message consumers (not web servers), don't rely on the cluster 'listening' event:
const cluster = require('cluster');
const os = require('os');
if (cluster.isPrimary) {
// Fork workers for background processing
for (let i = 0; i < os.cpus().length; i++) {
cluster.fork();
}
cluster.on('exit', (worker) => {
console.log('Worker died, restarting...');
cluster.fork(); // Restart dead workers
});
// Don't use cluster.on('listening') for non-server workloads
} else {
// Worker: Create a message consumer, NOT a listening server
const consumer = new RabbitMQConsumer();
consumer.start()
.then(() => console.log('Consumer started'))
.catch((err) => {
console.error('Consumer failed:', err);
process.exit(1);
});
}Create a simple test file to verify clustering works with a listening server:
// test-cluster.js
const cluster = require('cluster');
const http = require('http');
const os = require('os');
const PORT = process.env.PORT || 8000;
if (cluster.isPrimary) {
console.log('Primary process ' + process.pid + ' starting...');
// Fork workers
for (let i = 0; i < os.cpus().length; i++) {
cluster.fork();
}
// Listen for 'listening' event from workers
cluster.on('listening', (worker, address) => {
console.log('Worker ' + worker.process.pid + ' listening on port ' + address.port);
});
cluster.on('exit', (worker, code, signal) => {
console.log('Worker ' + worker.process.pid + ' exited');
cluster.fork(); // Respawn
});
} else {
// Worker: Create a listening server
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Response from worker ' + process.pid + '\n');
});
server.listen(PORT, () => {
console.log('Worker ' + process.pid + ' listening on port ' + PORT);
});
}Run with: node test-cluster.js and visit http://localhost:8000
Cluster module behavior changed over Node.js versions. Ensure you're using cluster.isPrimary (Node 16+) instead of the older cluster.isMaster:
// Modern (Node 16+)
if (cluster.isPrimary) {
// Fork workers
} else {
// Worker code
}
// Older versions (deprecated)
if (cluster.isMaster) {
// This still works but is deprecated
}If you're on an older Node.js version, update to Node 18 LTS or later for better cluster support and to avoid deprecated APIs.
Advanced notes
Round-robin vs. Shared Socket Handles: By default, Node.js uses round-robin load balancing on non-Windows platforms, where the primary process coordinates connection distribution to workers. On Windows, file handles are shared directly with workers. Both require workers to call .listen() to properly emit the 'listening' event that the cluster module expects and to receive connections.
Message Queue and Background Job Services: If you're building a worker pool for background jobs (Kafka, RabbitMQ, Bull queue, etc.), you may not need the cluster module at all. The cluster module is specifically designed for distributing network connections. Consider using dedicated worker libraries like bull, node-resque, bee-queue, or worker_threads for better isolation and control.
Sticky Sessions: If you're using cluster for HTTP servers, note that load balancing is per-connection, not per-request. Client sessions may be distributed across different workers. Use a shared session store (Redis) or sticky routing if session persistence matters for your application.
Graceful Shutdown: Always implement graceful shutdown handlers in workers. Use process.on('SIGTERM') or process.on('SIGINT') to close servers before exiting, allowing in-flight requests to complete.
Frequently asked questions
- What does "ERR_CLUSTER_LISTENING_ERROR" mean?
- js cluster module is designed to distribute incoming connections across multiple worker processes. listen() on a server object (like an HTTP server), it signals to the cluster module that it has a listening server ready to accept connections. If you see this error, it means your code structure is incorrect.
- How do I fix "ERR_CLUSTER_LISTENING_ERROR"?
- This error occurs when worker processes in a Node.js cluster module are trying to emit 'listening' events but no actual listening server exists in the worker processes. The cluster module expects workers to have a net.Server instance listening on a port to handle incoming connections.
- What causes "ERR_CLUSTER_LISTENING_ERROR"?
- Worker processes do not call .listen() on an http.Server or net.Server instance Attempting to use the cluster module with non-network-based services (message queues, background jobs) that don't create listening servers Primary process is attempting to listen() when it should only fork workers and let workers listen
- Is the "ERR_CLUSTER_LISTENING_ERROR" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- ๐Node.js Official Documentation
- ๐