Download

MongoTopologyClosedError: Topology is closed

Your code closed the MongoClient while an operation, or connect() itself, was still waiting for a server. Close the client once, when the app shuts down, after every operation has finished, and share one client instead of closing it per request.

MongoDB error· Tested on Node.js driver 6.20.0 and 6.16.0; MongoDB 8.0.32· Updated 11 October 2026

Topology is closed

What it means

A MongoClient keeps a picture of the servers it talks to (the driver calls it the topology) and a pool of connections to them. client.close() shuts that down. Anything still waiting on it, such as connect() or a query that hasn’t been given a server yet, fails with MongoTopologyClosedError: Topology is closed. It comes from the driver, not from MongoDB: the server never saw the operation.

Closing at the wrong moment shows up in a few forms, depending on where the operation was when the client closed:

MessageWhen
MongoTopologyClosedError: Topology is closedclose() ran while connect() or a query was waiting for a server
MongoNotConnectedError: Client must be connected before running operationsA query ran after close() had finished
MongoExpiredSessionError: Cannot use a session that has endedA query started while close() was still running
MongoClientClosedError: Operation interrupted because client was closedclose() ran while a query was running on the server (driver 6.20)

Common causes

  1. A missing await. client.close() in a finally block runs before a query that wasn’t awaited, or close() itself isn’t awaited and the next request uses the client.
  2. A client closed per request. A handler closes the shared client when it’s done, while other requests are still using it.
  3. Serverless functions that close the client at the end of an invocation and reuse the same module-level client in the next one.
  4. Tests. afterAll closes the client while a query from a test that didn’t await it is still pending, or one test file closes a client another file shares.
  5. The server can’t be reached. While the driver waits up to 30 seconds for a server, any close() (from a shutdown handler or a test timeout) turns the wait into this error. The real problem is the connection: see server selection errors.

How to fix it

Create one client and close it at shutdown

A MongoClient is meant to be shared: it manages its own pool. Create it once when the app starts, reuse it everywhere, and close it only when the process ends:

const { MongoClient } = require("mongodb")

const client = new MongoClient(process.env.MONGODB_URI)
const db = client.db("shop")

process.on("SIGTERM", async () => {
  await client.close()
  process.exit(0)
})

connect() is optional since driver 4.7: the first operation connects. Don’t call close() in a request handler.

Await everything before closing

In scripts, make sure every operation has finished first:

try {
  await orders.insertMany(docs)
  await orders.createIndex({ placedAt: -1 })
} finally {
  await client.close()
}

With Promise.all, await the whole set before the finally runs. A lint rule such as @typescript-eslint/no-floating-promises finds promises nobody awaited.

Reuse the client in serverless functions

Create the client outside the handler and don’t close it at the end of each call, so a warm function reuses its connections.

In tests, close in one place

Share one client across a test file, close it in afterAll, and await every query in the tests.

Fix the connection if nothing was reachable

If the error comes after a long pause, add serverSelectionTimeoutMS=5000 to the URL so the real cause (ECONNREFUSED, ENOTFOUND, a timeout) appears within five seconds instead of being cut off by close().

Reproduce it

Node.js 25 with the Node.js driver 6.20.0, against the MongoDB 8.0.32 test server. A client pointed at a port where nothing listens, closed half a second after a query started:

const client = new MongoClient("mongodb://localhost:37099/?serverSelectionTimeoutMS=5000")
const pending = client.db("shop").collection("orders").findOne({})
setTimeout(() => client.close(), 500)
await pending
MongoTopologyClosedError: Topology is closed

A client for the working server, closed without awaiting the connect() before it:

const connecting = client.connect()
client.close()
await connecting
MongoTopologyClosedError: Topology is closed

A query after that close had finished:

MongoNotConnectedError: Client must be connected before running operations

client.close() not awaited, then a query straight away:

MongoExpiredSessionError: Cannot use a session that has ended

A query running a slow $where on the server when close() ran gave MongoClientClosedError: Operation interrupted because client was closed with the driver 6.20.0; with 6.16.0 the query finished first. Driver 6.16.0 gave the same messages for the other cases. A client never connected explicitly ran its query without an error.

In Inlet

Paste the connection URL your app uses (mongodb:// or mongodb+srv://) and Inlet fills the connection form, so you can check the server answers outside your code. Collections show as tables and queries use mongosh syntax, so you can confirm what a script wrote before it closed.

Inlet: a database client for the Mac

One native app for PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and Redis. It explains errors where they happen, holds your edits until you save them, and keeps production read-only until you say so.

Version 0.1.0 · macOS 26 Tahoe or later · Apple silicon and Intel