This error occurs when the MongoDB driver's connection monitoring thread cannot maintain a stable connection to the server. The connection is closed before server selection can complete, typically due to network issues, authentication failures, or firewall restrictions.
The MongoServerSelectionError with "connection <monitor> to <host> closed" indicates that MongoDB's connection monitoring mechanism has failed to establish or maintain a connection to the specified host. The MongoDB driver uses background monitoring threads to continuously check the health and availability of MongoDB servers. When this monitoring connection closes unexpectedly, the driver cannot select a server for database operations, resulting in this error. This error is distinct from other connection errors because it specifically involves the monitoring thread rather than the application's data connections. The monitoring thread scans servers independently (by default every 10 seconds) to track server availability, topology changes, and server health. When this monitoring connection fails, it prevents the driver from making informed decisions about which server to route operations to, especially in replica set or sharded cluster deployments. The error typically manifests during initial connection attempts or when network conditions deteriorate, causing the driver to lose contact with the MongoDB server. Understanding this distinction is crucial for effective troubleshooting, as the root cause often lies in network configuration, authentication, or firewall rules rather than application code.
First, confirm that your MongoDB server is online and reachable from your application environment.
For MongoDB Atlas:
1. Log into MongoDB Atlas dashboard
2. Navigate to your cluster
3. Check cluster status is "Active" and healthy
For self-hosted MongoDB, check server status:
# Check if MongoDB process is running
ps aux | grep mongod
# Check MongoDB service status
sudo systemctl status mongod
# Test connectivity from application server
telnet your-mongodb-host 27017
# or
nc -zv your-mongodb-host 27017If the server is unreachable, you'll see connection refused or timeout errors. Ensure the MongoDB service is started and listening on the correct port.
If using MongoDB Atlas, the most common cause is IP address restrictions.
1. Go to MongoDB Atlas dashboard
2. Navigate to Network Access (under Security)
3. Click "Add IP Address"
4. Options:
- Add your current IP address (for development)
- Add 0.0.0.0/0 to allow all IPs (NOT recommended for production)
- Add specific IP ranges for your cloud platform
For cloud deployments (Render, Railway, Vercel, etc.):
# Find your deployment's outbound IP addresses
# Render: Check Render dashboard under Service > Networking
# Railway: Railway uses dynamic IPs, consider using 0.0.0.0/0 or MongoDB Private Endpoints
# Vercel: Vercel Functions use dynamic IPs, upgrade to Enterprise for static IPsWait 1-2 minutes after adding IP addresses for changes to propagate across MongoDB Atlas clusters.
MongoDB Atlas and many production deployments require TLS/SSL encryption. If your connection string is missing TLS configuration, add it:
// Node.js with MongoDB driver
const { MongoClient } = require('mongodb');
// Add tls=true to connection string
const uri = 'mongodb+srv://username:[email protected]/database?retryWrites=true&w=majority&tls=true';
const client = new MongoClient(uri);For Mongoose:
const mongoose = require('mongoose');
// Connection string with TLS enabled
const uri = 'mongodb+srv://username:[email protected]/database?tls=true';
mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});MongoDB Atlas connection strings typically use mongodb+srv:// which automatically enables TLS. If using mongodb:// (non-SRV), explicitly add tls=true.
Incorrect username, password, or authentication database can cause connection monitor failures.
Check your connection string format:
// Correct format
mongodb+srv://USERNAME:[email protected]/DATABASE_NAME
// Common mistakes:
// 1. Special characters in password not URL-encoded
// 2. Wrong authentication database (authSource parameter)
// 3. Username/password mismatchURL-encode special characters in password:
// If password is: p@ssw0rd!
// Encode as: p%40ssw0rd%21
const password = 'p@ssw0rd!';
const encodedPassword = encodeURIComponent(password);
const uri = `mongodb+srv://user:${encodedPassword}@cluster.mongodb.net/db`;Test credentials using MongoDB Compass or mongosh:
# Test connection with mongosh
mongosh "mongodb+srv://username:[email protected]/database"If authentication fails, create a new database user in MongoDB Atlas:
1. Database Access → Add New Database User
2. Set username and password
3. Grant appropriate privileges
4. Update connection string with new credentials
Increase timeout values and enable automatic retry for unstable networks:
const { MongoClient } = require('mongodb');
const uri = 'mongodb+srv://username:[email protected]/database';
const client = new MongoClient(uri, {
serverSelectionTimeoutMS: 5000, // Timeout after 5s instead of 30s
socketTimeoutMS: 45000, // Close sockets after 45s of inactivity
connectTimeoutMS: 10000, // Give up initial connection after 10s
retryWrites: true, // Automatically retry write operations
retryReads: true, // Automatically retry read operations
});
async function connect() {
try {
await client.connect();
console.log('Connected to MongoDB');
} catch (error) {
console.error('Connection failed:', error.message);
// Implement exponential backoff retry logic
}
}For Mongoose:
const mongoose = require('mongoose');
mongoose.connect(uri, {
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000,
family: 4, // Force IPv4
});These settings help surface connection issues faster and handle transient network problems more gracefully.
Ensure your firewall allows outbound connections to MongoDB:
For Linux servers:
# Check if port 27017 is accessible
telnet cluster.mongodb.net 27017
# Allow outbound MongoDB traffic (if using ufw)
sudo ufw allow out 27017/tcp
# For iptables
sudo iptables -A OUTPUT -p tcp --dport 27017 -j ACCEPTFor Docker containers:
# docker-compose.yml
version: '3'
services:
app:
image: node:18
network_mode: bridge # Ensure container can reach external networks
dns:
- 8.8.8.8 # Use Google DNS for reliable hostname resolution
- 8.8.4.4For corporate networks:
- Check if proxy configuration is required
- Verify MongoDB ports (27017 or custom) are not blocked
- Test from a different network to isolate network-specific issues
For cloud platforms:
- AWS: Check Security Groups allow outbound traffic on MongoDB port
- GCP: Verify VPC firewall rules permit egress to MongoDB
- Azure: Check Network Security Groups (NSGs) allow outbound connections
DNS resolution failures can cause monitoring connections to close:
# Test DNS resolution for MongoDB Atlas cluster
nslookup cluster.mongodb.net
# Or use dig
dig cluster.mongodb.net
# Expected output should show IP addressesIf DNS resolution fails:
1. Use public DNS servers:
// In your application, force IPv4
const { MongoClient } = require('mongodb');
const client = new MongoClient(uri, {
family: 4, // Force IPv4, skip IPv6 resolution
});2. Update /etc/resolv.conf (Linux):
sudo nano /etc/resolv.conf
# Add reliable DNS servers
nameserver 8.8.8.8
nameserver 8.8.4.43. For Docker containers, specify DNS:
docker run --dns 8.8.8.8 --dns 8.8.4.4 your-imageMongoDB Atlas uses SRV records for mongodb+srv:// connections, which require working DNS resolution.
Connection Monitoring Internals: MongoDB drivers maintain separate monitoring connections to track server topology and health. These connections use a heartbeat mechanism (default: every 10 seconds via heartbeatFrequencyMS) to detect server failures, replica set elections, and topology changes. When a monitoring connection closes, it signals a fundamental connectivity issue rather than a transient application-level problem.
Connection Pool Behavior: The driver maintains a connection pool with configurable minimum (minPoolSize) and maximum (maxPoolSize) connections. When monitoring fails, the pool cannot populate or maintain healthy connections. Consider these pool settings for production:
const client = new MongoClient(uri, {
minPoolSize: 5, // Maintain minimum 5 connections
maxPoolSize: 50, // Allow up to 50 concurrent connections
maxIdleTimeMS: 60000, // Close idle connections after 60s
waitQueueTimeoutMS: 5000, // Wait max 5s for available connection
});IPv4 vs IPv6 Issues: Some environments have misconfigured IPv6, causing connection attempts to timeout. The family: 4 option forces IPv4 and can resolve connection issues in dual-stack environments where IPv6 is broken.
MongoDB Atlas Private Endpoints: For production environments with strict security requirements, MongoDB Atlas Private Endpoints (AWS PrivateLink, Azure Private Link, GCP Private Service Connect) eliminate IP whitelisting entirely by creating private network paths. This is the recommended approach for cloud deployments rather than whitelisting 0.0.0.0/0.
Driver Version Compatibility: Ensure your MongoDB driver version is compatible with your MongoDB server version. Driver version 4.0+ is recommended for MongoDB 4.4+, and version 5.0+ for MongoDB 6.0+. Check compatibility matrices in official MongoDB driver documentation.
Logging for Debugging: Enable detailed connection logging to diagnose issues:
const { MongoClient } = require('mongodb');
// Enable debug logging
const uri = 'mongodb+srv://...?retryWrites=true&w=majority&loggerLevel=debug';
const client = new MongoClient(uri, {
serverApi: '1',
monitorCommands: true, // Log all database commands
});
client.on('serverHeartbeatFailed', (event) => {
console.error('Heartbeat failed:', event);
});
client.on('serverClosed', (event) => {
console.error('Server connection closed:', event);
});Kubernetes and Container Orchestration: In Kubernetes environments, ensure pods have appropriate network policies and DNS configuration. Services may need longer grace periods for connections to establish during pod startup or rolling updates.
DivergentArrayError: For your own good, using document.save() to update an array which was selected using an $elemMatch projection will not work
How to fix "DivergentArrayError: For your own good, using document.save() to update an array which was selected using an $elemMatch projection will not work" in MongoDB
MongoServerError: bad auth : authentication failed
How to fix "MongoServerError: bad auth : authentication failed" in MongoDB
CannotCreateIndex: Cannot create index
CannotCreateIndex: Cannot create index
StaleShardVersion: shard version mismatch
How to fix "StaleShardVersion: shard version mismatch" in MongoDB
MongoOperationTimeoutError: Operation timed out
How to fix "MongoOperationTimeoutError: Operation timed out" in MongoDB