{"record":{"id":"c73142e0663a308a","repo":"mongodb/node-mongodb-native","slug":"server-is-closed","errorCode":null,"errorMessage":"Server is closed","messagePattern":"Server is closed","errorType":"exception","errorClass":"MongoServerClosedError","httpStatus":null,"severity":"error","filePath":"src/sdam/server.ts","lineNumber":287,"sourceCode":"    this.emit('closed');\n  }\n\n  /**\n   * Immediately schedule monitoring of this server. If there already an attempt being made\n   * this will be a no-op.\n   */\n  requestCheck(): void {\n    if (!this.loadBalanced) {\n      this.monitor?.requestCheck();\n    }\n  }\n\n  public async command<TResult>(\n    operation: AbstractOperation<TResult>,\n    timeoutContext: TimeoutContext\n  ): Promise<InstanceType<typeof operation.SERVER_COMMAND_RESPONSE_TYPE>> {\n    if (this.s.state === STATE_CLOSING || this.s.state === STATE_CLOSED) {\n      throw new MongoServerClosedError();\n    }\n    const session = operation.session;\n\n    let conn = session?.pinnedConnection;\n\n    this.incrementOperationCount();\n    if (conn == null) {\n      try {\n        conn = await this.pool.checkOut({ timeoutContext, signal: operation.options.signal });\n      } catch (checkoutError) {\n        this.decrementOperationCount();\n        if (!(checkoutError instanceof PoolClearedError)) this.handleError(checkoutError);\n        throw checkoutError;\n      }\n    }\n\n    let reauthPromise: Promise<void> | null = null;\n    const cleanup = () => {","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/sdam/server.ts#L269-L305","documentation":"Thrown by Server.command() (src/sdam/server.ts:287) as MongoServerClosedError when an operation is attempted against a server whose internal state is STATE_CLOSING or STATE_CLOSED. The server (a single connection-pool owner within the topology) has been or is being torn down, so no command can be sent. Typically encountered after MongoClient.close() or during topology reconfiguration.","triggerScenarios":"Using a collection/db/client reference after client.close() resolved, issuing queries during shutdown, or holding a cursor/server reference that outlived the client. Also arises during failover when the targeted server is removed.","commonSituations":"Calling close() then reusing the client, shared singletons in long-running processes that get closed by a test teardown, or racing operations during application shutdown.","solutions":["Ensure no in-flight operations when calling MongoClient.close(); await all promises first.","Do not reuse a closed client — create a new MongoClient.","Coordinate shutdown ordering: stop accepting new work, drain in-flight ops, then close.","Catch MongoServerClosedError to avoid crashing during graceful shutdown."],"exampleFix":"// before\nawait client.close();\nawait collection.findOne({}); // throws\n// after\nawait collection.findOne({});\nawait client.close();","handlingStrategy":"try-catch","validationCode":"let closed = false;\nclient.on('close', () => { closed = true; });\nasync function safeFind() {\n  if (closed) throw new Error('client is closed');\n  return collection.findOne({});\n}","typeGuard":"function isClientClosed(client): boolean {\n  return client.topology == null;\n}","tryCatchPattern":"try {\n  await collection.findOne({});\n} catch (e) {\n  if (e instanceof MongoServerClosedError || /Server is closed/.test(e.message)) {\n    // skip or reconnect with a new client\n  }\n  throw e;\n}","preventionTips":["Await all in-flight operations before calling client.close().","Never reuse a closed MongoClient; construct a new one.","Coordinate shutdown: stop new work, drain ops, then close.","Track a 'closed' flag in application code alongside the client lifecycle."],"tags":["sdam","lifecycle","connection","shutdown"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}