How to fix MaxListenersExceededWarning: Possible EventEmitter memory leak detected in Node.js

Node.jsINTERMEDIATEMEDIUMUpdated Dec 22, 2025· 164 views

This warning indicates that more than the default 10 listeners have been added to an EventEmitter without being removed, potentially causing memory leaks. Node.js warns you to either remove unused listeners, use emitter.setMaxListeners() to increase the limit, or refactor to avoid accumulating listeners.

Quick fix

Fixes MaxListenersExceededWarning

(node:12345) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 connection listeners added.
  1. Identify which event has too many listeners
  2. Remove listeners when they are no longer needed
  3. Use emitter.once() for one-time event handlers
  4. Increase the listener limit if appropriate
node.js — error
(node:12345) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 connection listeners added.
MaxListenersExceededWarning: Possible EventEmitter memory leak detected

What this error means

Node.js EventEmitter instances have a safety limit on the number of listeners that can be attached to a single event. By default, this limit is 10 listeners per event. When you add more listeners than this limit, Node.js emits the MaxListenersExceededWarning to alert you of a potential memory leak. This warning suggests that listeners are being added without corresponding removal, which can cause memory to grow unbounded over time. The warning is a best-practice check—your code may still function correctly, but it's a sign that listener management should be reviewed. The warning often appears when making repeated HTTP requests with custom agents, creating many database connections, or subscribing to socket/stream events without proper cleanup.

Typical symptoms

  • MaxListenersExceededWarning appears in stderr during application startup or execution
  • Warning message shows the specific event name and number of listeners added (e.g., '11 connection listeners added')
  • Application continues to run despite the warning
  • Memory usage grows over time as listeners accumulate without being removed
  • Warnings appear in test suites or when making multiple HTTP requests

Common causes

  1. Event listeners are registered inside loops or repeatedly-called functions without removing old listeners first
  2. Using custom HTTP/HTTPS agents with keepAlive enabled across multiple requests without proper listener cleanup
  3. Creating socket or stream connections repeatedly without removing listeners after the connection closes
  4. Library code or third-party modules internally adding many listeners without proper removal
  5. Not using emitter.once() for one-time events, instead using emitter.on() and manually removing later (then forgetting to remove)

How to fix "MaxListenersExceededWarning: Possible EventEmitter memory leak detected"

1Identify which event has too many listeners

The warning message will tell you which event name and how many listeners were added. Look for patterns like:

bash
(node:12345) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 connection listeners added.

Note the event name ('connection' in this example) and the listener count (11). Run with the trace-warnings flag for more details:

bash
node --trace-warnings app.js
2Remove listeners when they are no longer needed

Save references to your listener functions and remove them after use:

javascript
const server = require('http').createServer();
const onConnection = (socket) => {
  console.log('Client connected');
};

// Add listener
server.on('connection', onConnection);

// Remove listener when no longer needed
server.removeListener('connection', onConnection);
// Or remove all listeners:
server.removeAllListeners('connection');

Always remove listeners that are only needed temporarily. For one-time events, use emitter.once() instead of emitter.on().

3Use emitter.once() for one-time event handlers

For event handlers that should only fire once, use .once() instead of .on(). The listener is automatically removed after firing:

javascript
const socket = require('net').createConnection();

// Good: listener automatically removed after first 'connect' event
socket.once('connect', () => {
  console.log('Connected once');
});

// Not ideal: listener persists after first event
socket.on('connect', () => {
  console.log('Connected');
});

This prevents accidental listener accumulation.

4Increase the listener limit if appropriate

If you have reviewed your code and verified that listeners are being added and removed correctly, you can increase the listener limit using setMaxListeners():

javascript
const emitter = new require('events').EventEmitter();

// Increase limit to 20 listeners
emitter.setMaxListeners(20);

// Or disable the limit entirely (use with caution)
emitter.setMaxListeners(0); // 0 = unlimited

You can also set the default limit for all new EventEmitter instances:

javascript
require('events').EventEmitter.defaultMaxListeners = 20;

Important: Only increase the limit after confirming listeners are being properly managed. Blindly increasing the limit masks underlying memory leak issues.

5Fix common patterns that accumulate listeners

Check for these common patterns that cause listener accumulation:

Pattern 1: Registering listeners in loops or repeated function calls

javascript
// Bad: listener added every time function is called
function fetchData() {
  const request = http.get(url);
  request.on('response', handleResponse); // Added repeatedly!
}

for (let i = 0; i < 1000; i++) {
  fetchData(); // 1000 listeners added
}

// Good: use once() or handle cleanup
function fetchData() {
  const request = http.get(url);
  request.once('response', handleResponse); // Auto-removed after first call
}

Pattern 2: Custom HTTP agents with keepAlive

javascript
// Bad: each request adds listeners to the same agent
const agent = new http.Agent({ keepAlive: true });
for (let i = 0; i < 1000; i++) {
  http.get(url, { agent }, callback);
}

// Good: reuse the same agent with setMaxListeners
const agent = new http.Agent({ keepAlive: true });
agent.setMaxListeners(100);
for (let i = 0; i < 1000; i++) {
  http.get(url, { agent }, callback);
}

Pattern 3: Stream event listeners

javascript
// Bad: listeners not removed
const fs = require('fs');
function readFile() {
  const stream = fs.createReadStream('file.txt');
  stream.on('data', handleData); // Added repeatedly
}

// Good: use once() or proper cleanup
function readFile() {
  const stream = fs.createReadStream('file.txt');
  stream.once('data', handleData);
  stream.once('end', () => stream.destroy());
}
6Debug listener accumulation with inspection methods

Use Node.js EventEmitter methods to inspect listener state:

javascript
const emitter = new require('events').EventEmitter();

// Add some listeners
emitter.on('test', () => {});
emitter.on('test', () => {});

// Check current listener count
console.log(emitter.listenerCount('test')); // 2

// Check the maximum limit
console.log(emitter.getMaxListeners()); // 10 (default)

// Get all listeners for an event
console.log(emitter.listeners('test')); // Array of listener functions

// Monitor for listener changes
emitter.on('newListener', (event, func) => {
  console.log(`Listener added to ${event} event`);
});

emitter.on('removeListener', (event, func) => {
  console.log(`Listener removed from ${event} event`);
});

Use these methods during development to track listener lifecycle and catch accumulation early.

Advanced notes

The default limit of 10 listeners is intentionally low to catch potential memory leaks during development. In production, you may legitimately have more listeners for certain events (like database connection 'connect' events in a pool), so increasing the limit is acceptable after code review.

Node.js will not throw an error when the listener limit is exceeded—it only emits the warning and continues executing. This means buggy code that accumulates listeners will appear to work initially but will eventually consume all available memory.

When using HTTP/HTTPS with custom agents, the limit is often hit on the socket-level emitters (like TLSSocket) rather than the main server/client emitter. The warning may point to internal Node.js listeners, which is why inspecting your own code may not reveal the issue immediately—check for agent reuse and keepAlive settings.

For applications that legitimately create many connections (like connection pools or load balancers), consider using a separate EventEmitter per connection pool or increasing the limit selectively rather than globally, to preserve warnings for code paths where leaks are less expected.

Frequently asked questions

What does "MaxListenersExceededWarning" mean?
js EventEmitter instances have a safety limit on the number of listeners that can be attached to a single event. By default, this limit is 10 listeners per event. js emits the MaxListenersExceededWarning to alert you of a potential memory leak.
How do I fix "MaxListenersExceededWarning"?
This warning indicates that more than the default 10 listeners have been added to an EventEmitter without being removed, potentially causing memory leaks. Node.js warns you to either remove unused listeners, use emitter.setMaxListeners() to increase the limit, or refactor to avoid accumulating listeners.
What causes "MaxListenersExceededWarning"?
Event listeners are registered inside loops or repeatedly-called functions without removing old listeners first Using custom HTTP/HTTPS agents with keepAlive enabled across multiple requests without proper listener cleanup Creating socket or stream connections repeatedly without removing listeners after the connection closes
Is the "MaxListenersExceededWarning" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading