Fix MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
On this page
- 1. MongoDB is not running
- 2. The error says ::1 — use 127.0.0.1 instead of localhost
- 3. Your app runs in Docker
- 4. Your environment variable is empty
- 5. MongoDB Atlas: your IP is not allowed
- 6. A firewall or wrong port
- Quick checklist
- Read the full error, not just the first line
- Fixing querySrv errors on some networks
- Don’t start the server before the database is ready
- Watch the connection after startup
- Serverless platforms: reuse the connection
- Test the network path directly
- Skip local installs: run MongoDB in Docker
- Frequently asked questions
- Oh hi there 👋It’s nice to meet you.
- Sign up to receive awesome content in your inbox.
You start your Node.js app and get this instead of “MongoDB connected”:
MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
Or the IPv6 version, which confuses a lot of people:
MongooseServerSelectionError: connect ECONNREFUSED ::1:27017
ECONNREFUSED means your app reached the machine, but nothing accepted the connection on that port. Mongoose waits for a server (30 seconds by default), gives up, and throws MongooseServerSelectionError. The fixes below are ordered from most to least likely.
1. MongoDB is not running
This is the cause most of the time, especially after a restart. Start the server for your system:
| System | Start MongoDB | Check it is running |
|---|---|---|
| Ubuntu, Debian, most Linux | sudo systemctl start mongod |
sudo systemctl status mongod |
| macOS (Homebrew) | brew services start mongodb-community |
brew services list |
| Windows | Start the “MongoDB Server” service in Services, or net start MongoDB as administrator |
Services window |
| Docker | docker start mongo or docker compose up -d |
docker ps |
Then confirm you can connect without your app:
mongosh "mongodb://127.0.0.1:27017"
If mongosh also fails, the problem is the server, not your code. On Linux, sudo journalctl -u mongod -n 50 shows why it failed to start. A full disk or wrong permissions on /var/lib/mongodb are common reasons.
2. The error says ::1 — use 127.0.0.1 instead of localhost
Since Node.js 17, localhost can resolve to the IPv6 address ::1 first. MongoDB listens only on the IPv4 address 127.0.0.1 by default, so the connection is refused even though MongoDB is running. Change your connection string:
# Before
MONGODB_URI=mongodb://localhost:27017/myapp
# After
MONGODB_URI=mongodb://127.0.0.1:27017/myapp
This one-line change fixes the ::1:27017 version of the error almost every time.
3. Your app runs in Docker
Inside a container, 127.0.0.1 means the container itself, not your computer or the MongoDB container. With Docker Compose, use the service name as the host:
services:
api:
build: .
environment:
MONGODB_URI: mongodb://mongo:27017/myapp
depends_on:
- mongo
mongo:
image: mongo:7
ports:
- "27017:27017"
If MongoDB runs on your computer and only the app is in Docker, use host.docker.internal as the host on Docker Desktop.
4. Your environment variable is empty
If dotenv loads after the connection code runs, or the variable name has a typo, Mongoose receives undefined. Log it once to check:
require('dotenv').config(); // must run before you read process.env
const mongoose = require('mongoose');
console.log('Connecting to', process.env.MONGODB_URI?.replace(/\/\/.*@/, '//***@'));
mongoose
.connect(process.env.MONGODB_URI, { serverSelectionTimeoutMS: 10000 })
.then(() => console.log('MongoDB connected'))
.catch((err) => {
console.error('MongoDB connection failed:', err.message);
process.exit(1);
});
The replace hides the password in your logs. Lowering serverSelectionTimeoutMS to 10 seconds makes the error appear faster while you debug.
5. MongoDB Atlas: your IP is not allowed
With Atlas the message often mentions a timeout or the cluster host instead of ECONNREFUSED, but the cause is the same: the connection never got through. Open Atlas, go to Network Access, and add your current IP address. Hosting platforms such as Render or Railway may use changing IPs; for those, check the platform’s docs for its outbound IP addresses.
Also check the string itself. An unencoded @ or # in the password, or a leftover <db_password> placeholder, breaks the connection. Paste your string into the MongoDB connection string checker to find these in seconds.
6. A firewall or wrong port
If MongoDB runs on another server, its config file may only allow local connections. Check net.bindIp in /etc/mongod.conf and your cloud firewall rules. Only open port 27017 to the specific IPs that need it, never to the whole internet, and always with authentication on.
Quick checklist
- Is
mongodrunning? Test withmongosh. - Does the error say
::1? Use127.0.0.1. - In Docker? Use the service name.
- Is
process.env.MONGODB_URIdefined whenconnect()runs? - Using Atlas? Check Network Access and the password encoding.
Read the full error, not just the first line
MongooseServerSelectionError is a wrapper. The real cause sits inside it, in err.reason and in the message that follows the error name. Log the whole thing once:
mongoose.connect(process.env.MONGODB_URI).catch((err) => {
console.error(err.name, '-', err.message);
if (err.reason) console.error('Reason:', err.reason.type, [...err.reason.servers.keys()]);
});
The message usually names one of these underlying problems, and each points to a different fix:
| Text in the message | What it means | Where to look |
|---|---|---|
ECONNREFUSED |
Nothing is listening on that host and port | Is MongoDB running? Is the host right? (sections 1–3) |
ETIMEDOUT or a plain timeout |
Packets are being dropped, usually by a firewall | Atlas Network Access, cloud firewall rules |
querySrv ENOTFOUND or ECONNREFUSED _mongodb._tcp… |
The DNS lookup for a mongodb+srv:// address failed |
Typo in the cluster name, or a network that blocks SRV DNS lookups |
bad auth or Authentication failed |
The connection worked; the username or password is wrong | Database user in Atlas, password encoding, authSource |
getaddrinfo ENOTFOUND |
The host name doesn’t exist | Typo in the host, or an undefined environment variable |
Fixing querySrv errors on some networks
A mongodb+srv:// address needs a special DNS lookup (an SRV record). Some office, college and mobile networks, and some routers, don’t answer these lookups properly, so the same code works at home and fails elsewhere. Three fixes, from easiest to most thorough:
- Switch your computer’s DNS server to a public resolver such as 8.8.8.8 or 1.1.1.1 and try again.
- Try a different network, such as a phone hotspot, to confirm the network is the problem.
- Use the standard connection string instead. In Atlas, choose the connection option for older drivers to get a
mongodb://string that lists every server, which needs no SRV lookup.
Paste either string into the MongoDB connection string checker to spot typos, missing encoding and leftover placeholders.
Don’t start the server before the database is ready
A common pattern is to call mongoose.connect() and app.listen() side by side. The API then accepts requests that fail for the first few seconds, or forever if the database never connects. Connect first, then listen:
const mongoose = require('mongoose');
const app = require('./app');
async function start() {
try {
await mongoose.connect(process.env.MONGODB_URI, { serverSelectionTimeoutMS: 10000 });
console.log('MongoDB connected');
app.listen(process.env.PORT || 5000, () => console.log('API listening'));
} catch (err) {
console.error('Could not connect to MongoDB:', err.message);
process.exit(1); // PM2, Docker or your host restarts the app
}
}
start();
Exiting with an error code is better than staying up half-broken: your process manager restarts the app, and your monitoring sees a clear failure instead of a server that looks healthy but can’t do anything.
Watch the connection after startup
Connections can also drop later, for example when Atlas performs maintenance or your server’s network blips. Mongoose reconnects automatically, and you can log what happens:
mongoose.connection.on('disconnected', () => console.warn('MongoDB disconnected'));
mongoose.connection.on('reconnected', () => console.log('MongoDB reconnected'));
mongoose.connection.on('error', (err) => console.error('MongoDB error:', err.message));
During a short outage, queries wait for the connection to come back, up to the server selection timeout, instead of failing immediately. Combine these logs with a /health endpoint that reports the database state, as shown in the Node.js production checklist.
Serverless platforms: reuse the connection
On Vercel, Netlify Functions or AWS Lambda, every cold start runs your code from scratch. Calling mongoose.connect() on every request opens a flood of connections and can hit Atlas connection limits, which then shows up as timeouts. Cache the connection on the global object:
// lib/db.js
const mongoose = require('mongoose');
let cached = global._mongoose || (global._mongoose = { conn: null, promise: null });
async function connectDB() {
if (cached.conn) return cached.conn;
if (!cached.promise) {
cached.promise = mongoose.connect(process.env.MONGODB_URI, { maxPoolSize: 5 });
}
cached.conn = await cached.promise;
return cached.conn;
}
module.exports = connectDB;
Test the network path directly
If you still aren’t sure whether the problem is your code or the network, test the port without Node at all. On macOS and Linux, nc -vz 127.0.0.1 27017 reports whether the port accepts connections. On Windows PowerShell, use Test-NetConnection 127.0.0.1 -Port 27017. If these fail, no change to your JavaScript will help; fix the server, firewall or network first.
Skip local installs: run MongoDB in Docker
Many ECONNREFUSED problems come from a broken or half-upgraded local MongoDB installation. If you have Docker, a clean database is one command away, and it behaves the same on Windows, macOS and Linux:
docker run -d --name mongo -p 27017:27017 -v mongo-data:/data/db mongo:7
Connect with mongodb://127.0.0.1:27017/myapp. The -v mongo-data:/data/db part stores your data in a Docker volume, so it survives when the container is stopped or recreated. Start it again later with docker start mongo.
Frequently asked questions
Why does it work in mongosh but not in Node.js?
Usually because mongosh connects to 127.0.0.1 while your app uses localhost, which Node.js resolves to ::1. Use the same address in both.
How do I stop my app from crashing when MongoDB is down?
Catch the error from mongoose.connect(), log it, and either exit so your process manager restarts the app, or retry after a delay. Don’t start the HTTP server until the database is connected.
What does “server selection” mean?
The driver looks for a suitable MongoDB server to send your query to. If it can’t find one within serverSelectionTimeoutMS, it throws a server selection error. The reason underneath, such as ECONNREFUSED, tells you why.
Why does the error take 30 seconds to appear?
Mongoose keeps trying to find a server until serverSelectionTimeoutMS runs out, which defaults to 30 seconds. Set it to 5–10 seconds during development to see errors faster.
Can a wrong password cause ECONNREFUSED?
No. A wrong password produces an authentication error after the connection succeeds. ECONNREFUSED always means the connection itself was refused.




