Fix "MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017"
ECONNREFUSED on port 27017 means nothing is listening there. Start mongod, check the port, fix ::1 vs 127.0.0.1, and connect correctly from Docker.
Quick Answer
Your client reached the machine, but no MongoDB server is listening on that port. Almost always, mongod isn't running. Start it:
# macOS (Homebrew)
brew services start mongodb-community
# Linux (systemd)
sudo systemctl start mongod
# Docker
docker run -d --name mongo -p 27017:27017 mongo:7
Then test with mongosh "mongodb://127.0.0.1:27017". If MongoDB is running and you still get the error, the cause is one of the others below.
What the error means
"Connection refused" comes from the operating system, not from MongoDB. The client reached the host, and the host answered that nothing accepts connections on that port. Each client wraps it differently, and they don't all fail at the same speed:
| Client | Exact error | How long before it fails |
|---|---|---|
| mongosh 2.x | MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017 | About 1 second |
| Node.js driver 6 | MongoServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017 | 30 seconds (serverSelectionTimeoutMS) |
| Mongoose 8 | MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017 | 30 seconds |
| PyMongo 4 | ServerSelectionTimeoutError: 127.0.0.1:27017: [Errno 61] Connection refused | 30 seconds |
(Errno 61 is macOS, Errno 111 is Linux.) The drivers keep retrying until server selection gives up, so a refused connection looks like a 30-second hang in your app even though the OS refused it instantly. If the message says timed out with no ECONNREFUSED in it, the packets aren't being answered at all; see server selection timeout.
What we found testing this
- Drivers wait the full timeout on a refusal. With nothing listening, mongosh failed in about a second, but the Node.js driver took 30.0 s and PyMongo 30.2 s, because both treat it as "no server selectable yet" and keep retrying. Lower the wait in development so failures show up fast:
serverSelectionTimeoutMS=3000made both fail in 3.0 s. - Seeing two addresses doesn't mean IPv6 is the problem. Connecting to
localhostfrom Node.js 22 with driver 6, the message wasconnect ECONNREFUSED ::1:27017, connect ECONNREFUSED 127.0.0.1:27017: the driver tried both loopback addresses and both were refused. Only when the message lists::1alone is the IPv6 fallback (Cause 2) the likely culprit. - Mongoose hides the error behind a buffering timeout. If you never await
mongoose.connect()and the server is down, queries fail withOperation `users.findOne()` buffering timed out after 10000msinstead of ECONNREFUSED. Await the connect call, or catch its error, to see the real cause. - A full disk makes mongod disappear. While writing this, a test container ran out of disk: inserts first failed with
No space left on device, then mongod exited, and the next connection got ECONNREFUSED. When the server "randomly" stops accepting connections, check free disk space (df -h) before anything else.
Causes at a glance
| Cause | How to tell | Fix |
|---|---|---|
| mongod isn't running | Nothing listening: lsof -iTCP:27017 -sTCP:LISTEN prints nothing | Start the service or container |
| It crashed on startup | The service shows as failed or keeps restarting | Read the log, usually a disk, permission or lock file problem |
| Wrong port | Something listens, but on a different port | Use the real port in the connection string |
::1 vs 127.0.0.1 | Error mentions ::1:27017 | Use 127.0.0.1 instead of localhost |
| Connecting from inside Docker | localhost in a container is the container itself | Use the service name or host.docker.internal |
Cause 1: mongod isn't running, or crashed
Check whether anything is listening on 27017:
lsof -iTCP:27017 -sTCP:LISTEN # macOS / Linux
brew services list | grep mongo # Homebrew
systemctl status mongod # systemd
If the service starts and immediately stops, the reason is in the log (/usr/local/var/log/mongodb/mongo.log or /opt/homebrew/var/log/mongodb/mongo.log on Homebrew, /var/log/mongodb/mongod.log on Linux). The usual suspects:
- The data directory doesn't exist or isn't writable by the user mongod runs as.
- The disk is full.
- A stale
mongod.lockafter an unclean shutdown. Don't delete it blindly: run mongod once in the foreground and read what it says. - An upgrade jumped versions. MongoDB only upgrades one major version at a time, so a data directory from 5.0 won't start on 7.0.
Cause 2: localhost resolves to ::1
If the error says ECONNREFUSED ::1:27017, your client resolved localhost to the IPv6 address, but mongod binds only to IPv4 127.0.0.1 by default. Node.js 17 and 18 use the first address the OS returns, which is often ::1. Newer Node.js versions fall back to the other address automatically, but older drivers and other runtimes still hit this.
The simplest fix is to stop saying localhost:
mongodb://127.0.0.1:27017/myapp
Alternatively, make mongod listen on IPv6 too with net.ipv6: true and bindIp: 127.0.0.1,::1 in mongod.conf.
Cause 3: wrong port or wrong host
Docker port mappings and custom configs move MongoDB off 27017 more often than you'd think. Check what port it actually uses:
docker ps --format '{{.Names}} {{.Ports}}' # e.g. 0.0.0.0:27018->27017/tcp
grep -A3 '^net:' /etc/mongod.conf # port and bindIp
With -p 27018:27017, you connect to 127.0.0.1:27018 from the host. If mongod runs on another machine, its bindIp must include an address that machine is reachable on, not just 127.0.0.1. Only open it up behind a firewall and with authentication enabled.
Cause 4: connecting from a Docker container
Inside a container, 127.0.0.1 is the container, not your computer. An app container connecting to mongodb://localhost:27017 gets refused even though MongoDB is running fine on the host.
| Where MongoDB runs | Connection string from the app container |
|---|---|
| Another service in the same Docker Compose file | mongodb://mongo:27017 (the service name) |
| On your host machine (Docker Desktop) | mongodb://host.docker.internal:27017 |
| On your host machine (Linux) | Add extra_hosts: ["host.docker.internal:host-gateway"], then use the same URL |
In Compose, depends_on only waits for the MongoDB container to start, not for MongoDB to accept connections. If the app connects in the first second or two, add a healthcheck (mongosh --eval 'db.runCommand({ ping: 1 })') and use condition: service_healthy.
Frequently Asked Questions
What does ECONNREFUSED 127.0.0.1:27017 mean?
Nothing is accepting connections on port 27017 of your own machine. Usually MongoDB is not running, or it is running on a different port.
Why does the error mention ::1:27017?
localhost resolved to the IPv6 loopback, but MongoDB only listens on IPv4 by default. Connect to 127.0.0.1 instead of localhost.
How do I check if MongoDB is running?
Run mongosh "mongodb://127.0.0.1:27017" --eval "db.runCommand({ ping: 1 })". If it prints ok: 1, the server is up. You can also check the service with brew services list or systemctl status mongod.
MongoDB runs in Docker. Why can't my app connect?
If the app is also in a container, localhost points at the app container. Use the Compose service name, or host.docker.internal for a database on the host.