Error Medic

MongoDB 'connection refused' Error: Complete Troubleshooting Guide

Fix MongoDB connection refused, authentication failed, timeout, and too many connections errors. Step-by-step diagnostic commands with root cause analysis.

Last updated:
Last verified:
2,614 words
Key Takeaways
  • MongoDB 'connection refused' is a TCP-level rejection — mongod is not running, not listening on the expected host/port, or blocked by a firewall; verify with `systemctl status mongod` and `ss -tlnp | grep 27017`
  • Secondary causes include: disk full (mongod crashes mid-write), too many open connections (OS ulimit hit), permission denied on data directory, or bindIp set to 127.0.0.1 blocking remote hosts
  • Authentication failed (error code 18) is distinct from connection refused — it happens after TCP succeeds; always specify `?authSource=admin` in the connection string and use `db.getUsers()` to verify credentials
  • Quick fix sequence: (1) confirm mongod is running, (2) check bindIp and port in mongod.conf, (3) test firewall with `nc -zv host 27017`, (4) check disk space and ulimits, (5) inspect `/var/log/mongodb/mongod.log` for the root cause
Fix Approaches Compared
MethodWhen to UseTimeRisk
Restart mongod serviceProcess crashed or was never started< 2 minLow
Fix bindIp in mongod.confRemote hosts get connection refused; local-only binding active5 min + restartMedium
Update firewall / security group rulesPort 27017 blocked by iptables, ufw, or AWS SG5–10 minMedium
Reset user credentials via mongoshAuthentication failed / SCRAM error (code 18)5 minLow
Increase maxIncomingConnections and OS ulimitsToo many open connections error in logs10 min + restartLow
Free disk space or expand volumeDisk full causes write failures and mongod crash15+ minHigh
Replica set resync (db.adminCommand resync)Secondary replication lag, RECOVERING state30 min – hoursHigh
mongod --repairWiredTiger corruption after unclean shutdown30+ min downtimeHigh

Understanding MongoDB Connection Errors

MongoDB connection errors fall into three distinct layers that must be diagnosed separately:

  1. TCP layerConnection refused (ECONNREFUSED): nothing is listening on the socket.
  2. Network/firewall layerConnection timed out (ETIMEDOUT): something is listening but packets are dropped.
  3. Application layerAuthentication failed, too many connections, not primary: TCP succeeded but MongoDB rejected the session.

The error from mongosh looks like:

Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed:
  SocketException: Error connecting to 127.0.0.1:27017 :: caused by ::
  Connection refused

From Python PyMongo:

pymongo.errors.ServerSelectionTimeoutError: localhost:27017:
  [Errno 111] Connection refused, Timeout: 30s

From Node.js Mongoose:

MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017

Always start at the TCP layer and work up.


Step 1: Verify mongod Is Running

The most common cause of connection refused is a stopped or crashed process.

# systemd (Ubuntu 18+, RHEL 7+, Debian 10+)
systemctl status mongod

# SysV init fallback
service mongod status

# Direct process check
ps aux | grep mongod | grep -v grep

# Verify what port mongod is listening on
ss -tlnp | grep 27017

If mongod is not running, read the log before restarting to understand why it crashed:

tail -50 /var/log/mongodb/mongod.log

Key log messages and their meanings:

  • Insufficient free space for journal files → disk full — fix disk before restarting
  • Too many open files → OS ulimit too low — increase before restarting
  • Address already in use → port conflict — find and kill the conflicting process
  • Permission denied opening: /var/lib/mongodb/WiredTiger → ownership issue — fix permissions
  • Invalid magic number or WT_ERROR → WiredTiger corruption — use --repair

Step 2: Check bindIp Configuration

Since MongoDB 3.6, the default bindIp is 127.0.0.1. Any connection from a non-localhost address — including a Docker container on the same host — will receive connection refused. This is the second most common cause.

grep -A 5 '^net:' /etc/mongod.conf

Typical default that blocks remote access:

net:
  port: 27017
  bindIp: 127.0.0.1

To allow remote connections, change bindIp and restart:

net:
  port: 27017
  bindIp: 0.0.0.0   # all interfaces, or list specific IPs: 127.0.0.1,10.0.1.5
systemctl restart mongod

Security note: Exposing 0.0.0.0 without a firewall is dangerous. Always restrict with a VPC security group or iptables rule that whitelists only trusted client IPs on port 27017.


Step 3: Diagnose Firewall and Network Issues

Test connectivity from the client machine:

# nc (netcat) — instant TCP handshake test
nc -zv mongo-host 27017

# telnet alternative
telnet mongo-host 27017

# Check iptables rules on the server
iptables -L INPUT -n --line-numbers | grep -E '(27017|REJECT|DROP)'

# Allow port from a specific client IP
iptables -I INPUT 1 -s 10.0.1.100 -p tcp --dport 27017 -j ACCEPT
iptables-save > /etc/iptables/rules.v4

# ufw (Ubuntu)
ufw allow from 10.0.1.100 to any port 27017
ufw status verbose

For AWS EC2: check the security group attached to the MongoDB instance and ensure port 27017 is open from the application server's security group or CIDR.


Step 4: Fix Authentication Failed Errors

Authentication errors occur after a successful TCP connection. MongoDB returns error code 18:

MongoServerError: Authentication failed.
{ ok: 0, errmsg: 'Authentication failed.', code: 18, codeName: 'AuthenticationFailed' }

Diagnose the user configuration:

# Connect without credentials (works only via localhost exception on fresh install,
# or if --auth is not enabled)
mongosh --host 127.0.0.1 --port 27017

# In mongosh — list all users in admin database
use admin
db.getUsers()

# Reset a user password
db.changeUserPassword('appuser', 'NewSecurePassword123!')

# Create a missing user
db.createUser({
  user: 'appuser',
  pwd: 'NewSecurePassword123!',
  roles: [{ role: 'readWrite', db: 'myapp' }]
})

# Verify roles
db.getUser('appuser')

Always include authSource in the connection string — missing it defaults to the target database, not admin:

# Correct connection string
mongosh 'mongodb://appuser:password@host:27017/myapp?authSource=admin'

# Or with URI components
mongosh --host host --port 27017 -u appuser -p password --authenticationDatabase admin myapp

Step 5: Fix Permission Denied on Data Directory

# Check current ownership
ls -la /var/lib/mongodb/

# Fix ownership — mongod must own its data and log directories
chown -R mongod:mongod /var/lib/mongodb/
chown -R mongod:mongod /var/log/mongodb/
chmod 750 /var/lib/mongodb/

# On RHEL/CentOS with SELinux enforcing
audit2why < /var/log/audit/audit.log | grep mongod
# Apply correct SELinux context if using a non-default data path
semanage fcontext -a -t mongod_var_lib_t '/data/mongodb(/.*)?'
restorecon -Rv /data/mongodb/

Step 6: Fix Too Many Connections

Log error: Too many open connections or driver error: connection pool is full.

# Check current connection counts
mongosh --eval 'db.serverStatus().connections' admin
# { current: 998, available: 2, totalCreated: 45201 }

# Check OS file descriptor limit for mongod process
cat /proc/$(pgrep mongod)/limits | grep 'Open files'

# Increase limits — add to /etc/security/limits.conf
echo 'mongod soft nofile 64000' >> /etc/security/limits.conf
echo 'mongod hard nofile 64000' >> /etc/security/limits.conf

# Also set in /etc/systemd/system/mongod.service.d/limits.conf
[Service]
LimitNOFILE=64000

# Reload and restart
systemctl daemon-reload && systemctl restart mongod

# Set cap in mongod.conf
# net:
#   maxIncomingConnections: 50000

Application-side — always configure connection pool size:

# PyMongo
client = MongoClient('mongodb://host:27017/', maxPoolSize=50, minPoolSize=5)

# Node.js Mongoose
mongoose.connect(uri, { maxPoolSize: 50 })

Step 7: Fix Disk Full Causing Crashes

When the disk fills up, mongod cannot write journal files and crashes. You will see ENOSPC in the log.

# Check disk usage
df -h /var/lib/mongodb
du -sh /var/lib/mongodb/* | sort -rh | head -10

# Get collection sizes from mongosh
mongosh mydb --eval 'db.stats({ scale: 1024 * 1024 })'

# Compact a collection to reclaim space (blocks collection, use during maintenance)
mongosh mydb --eval 'db.runCommand({ compact: "largecollection" })'

# Delete old data and run compact, then flush
mongosh admin --eval 'db.runCommand({ fsync: 1 })'

# Check and remove old journal files (only when mongod is stopped)
ls -lh /var/lib/mongodb/journal/

Step 8: Diagnose and Fix Replication Lag

High replication lag causes secondaries to enter RECOVERING state and reject read connections.

# Overall replica set health
mongosh --eval 'rs.status()' admin

# Lag per secondary
mongosh --eval 'rs.printSecondaryReplicationInfo()' admin

# Oplog window — if lag exceeds this, secondary must resync
mongosh local --eval 'db.oplog.rs.stats().maxSize'

# Find slow operations causing lag
mongosh admin --eval 'db.currentOp({ "active": true, "secs_running": { "$gt": 5 } })'

# Kill a long-running operation blocking replication
mongosh admin --eval 'db.killOp(<opid>)'

# Force a lagging secondary to resync (run on the secondary)
use admin
db.adminCommand({ resync: 1 })

Step 9: Diagnose Slow Queries and Timeouts

Driver-side: ServerSelectionTimeoutError or NetworkTimeout often indicate the primary is overloaded.

# Enable slow query profiling (slowms threshold = 100ms)
mongosh mydb --eval 'db.setProfilingLevel(1, { slowms: 100 })'

# Read slow query log
mongosh mydb --eval 'db.system.profile.find().sort({ ts: -1 }).limit(10).pretty()'

# Explain a slow query — look for COLLSCAN (full scan) instead of IXSCAN
mongosh mydb --eval 'db.mycollection.explain("executionStats").find({ status: "active" })'

# Add a missing index
mongosh mydb --eval 'db.mycollection.createIndex({ status: 1, createdAt: -1 })'

# List all indexes
mongosh mydb --eval 'db.mycollection.getIndexes()'

Step 10: Crash Recovery and Corruption Repair

After a power failure or OOM kill, mongod may log:

Invalid magic number for file: /var/lib/mongodb/collection-0.wt
Failed to open "/var/lib/mongodb/WiredTiger"

Always back up before repair:

systemctl stop mongod
cp -r /var/lib/mongodb /backup/mongodb-$(date +%F)

# Run the repair tool — rebuilds indexes and removes corrupt documents
mongod --repair --dbpath /var/lib/mongodb

# If --repair fails, try WiredTiger salvage mode:
# Add to mongod.conf temporarily:
# storage:
#   wiredTiger:
#     engineConfig:
#       configString: 'salvage=true'
# Start once, then remove configString and restart normally

systemctl start mongod
tail -f /var/log/mongodb/mongod.log

Frequently Asked Questions

bash
#!/usr/bin/env bash
# MongoDB Full Connection Diagnostic Script
# Run on the MongoDB host as root or with sudo.
# Usage: bash mongo-diag.sh [port] [data-dir] [log-file]

MONGO_PORT=${1:-27017}
MONGO_DATA=${2:-/var/lib/mongodb}
MONGO_LOG=${3:-/var/log/mongodb/mongod.log}
HR='================================================'

echo "$HR"
echo '=== 1. mongod process status ==='
echo "$HR"
if command -v systemctl &>/dev/null; then
  systemctl status mongod --no-pager 2>/dev/null || echo 'mongod unit not found'
else
  service mongod status 2>/dev/null || echo 'mongod service not found'
fi
ps aux | grep '[m]ongod' || echo 'No mongod process found in ps output'

echo ""
echo "$HR"
echo '=== 2. Port binding (is mongod listening?) ==='
echo "$HR"
ss -tlnp 2>/dev/null | grep ":${MONGO_PORT}" || \
  netstat -tlnp 2>/dev/null | grep ":${MONGO_PORT}" || \
  echo "Nothing is listening on port ${MONGO_PORT} — connection refused is expected"

echo ""
echo "$HR"
echo '=== 3. Localhost connectivity test ==='
echo "$HR"
nc -zv 127.0.0.1 "${MONGO_PORT}" 2>&1 && echo 'Port OPEN on localhost' || echo 'Port CLOSED on localhost (connection refused)'

echo ""
echo "$HR"
echo '=== 4. mongod.conf net section ==='
echo "$HR"
if [[ -f /etc/mongod.conf ]]; then
  grep -A 5 '^net:' /etc/mongod.conf
else
  echo '/etc/mongod.conf not found — check custom --config path'
fi

echo ""
echo "$HR"
echo '=== 5. Firewall rules (port 27017) ==='
echo "$HR"
iptables -L INPUT -n --line-numbers 2>/dev/null | grep -E "(${MONGO_PORT}|REJECT|DROP)" || echo 'No relevant iptables rules found'
ufw status verbose 2>/dev/null | grep -E "(${MONGO_PORT}|Status)" || true

echo ""
echo "$HR"
echo '=== 6. Disk space on data directory ==='
echo "$HR"
df -h "${MONGO_DATA}" 2>/dev/null || df -h / 
echo "--- Top 10 largest items in ${MONGO_DATA} ---"
du -sh "${MONGO_DATA}"/* 2>/dev/null | sort -rh | head -10

echo ""
echo "$HR"
echo '=== 7. Data directory permissions ==='
echo "$HR"
ls -la "${MONGO_DATA}" 2>/dev/null | head -8

echo ""
echo "$HR"
echo '=== 8. File descriptor (ulimit) for mongod ==='
echo "$HR"
MONGO_PID=$(pgrep mongod 2>/dev/null | head -1)
if [[ -n "$MONGO_PID" ]]; then
  echo "mongod PID: ${MONGO_PID}"
  cat "/proc/${MONGO_PID}/limits" 2>/dev/null | grep -E '(Open files|Max open)'
else
  echo 'mongod not running — cannot check process limits'
  echo "Current shell ulimit -n: $(ulimit -n)"
fi

echo ""
echo "$HR"
echo '=== 9. Last 40 lines of mongod log ==='
echo "$HR"
tail -40 "${MONGO_LOG}" 2>/dev/null || echo "Log not found at ${MONGO_LOG}"

echo ""
echo "$HR"
echo '=== 10. Live MongoDB diagnostics (requires access) ==='
echo "$HR"
if command -v mongosh &>/dev/null; then
  echo '--- Connection counts ---'
  mongosh --quiet --eval \
    'JSON.stringify(db.serverStatus().connections, null, 2)' admin 2>/dev/null || \
    echo 'Cannot connect — skipping live diagnostics'

  echo ''
  echo '--- Slow operations (running > 5s) ---'
  mongosh --quiet --eval \
    'db.currentOp({active:true,secs_running:{$gt:5}}).inprog.forEach(o => print(JSON.stringify({opid:o.opid,ns:o.ns,secs:o.secs_running,op:o.op,query:o.query})))' \
    admin 2>/dev/null || echo 'Cannot connect'

  echo ''
  echo '--- Replica set status ---'
  mongosh --quiet --eval \
    'try { rs.status().members.forEach(m => print(m.name, m.stateStr, "lag:", m.optimeDate)) } catch(e) { print("Not a replica set or cannot connect:", e.message) }' \
    admin 2>/dev/null || echo 'Cannot connect'
else
  echo 'mongosh not found in PATH — install MongoDB Shell to run live diagnostics'
fi

echo ""
echo "$HR"
echo 'Diagnostic complete. Match log entries above against the troubleshooting guide.'
echo "$HR"
E

Error Medic Editorial

The Error Medic Editorial team is composed of senior SREs and database engineers with hands-on experience running MongoDB at scale in production. Our guides are derived from real incident postmortems, peer-reviewed against official documentation, and tested on MongoDB 5.x through 7.x.

Sources

Related Guides