{"record":{"id":"cba67b4307350ea0","repo":"mongodb/node-mongodb-native","slug":"timed-out-during-connection-checkout","errorCode":null,"errorMessage":"Timed out during connection checkout","messagePattern":"Timed out during connection checkout","errorType":"exception","errorClass":"MongoOperationTimeoutError","httpStatus":null,"severity":"error","filePath":"src/cmap/connection_pool.ts","lineNumber":366,"sourceCode":"      timeout?.throwIfExpired();\n      return await (timeout ? Promise.race([promise, timeout]) : promise);\n    } catch (error) {\n      if (TimeoutError.is(error)) {\n        timeout?.clear();\n        waitQueueMember.cancelled = true;\n\n        this.emitAndLog(\n          ConnectionPool.CONNECTION_CHECK_OUT_FAILED,\n          new ConnectionCheckOutFailedEvent(this, 'timeout', waitQueueMember.checkoutTime)\n        );\n        const timeoutError = new WaitQueueTimeoutError(\n          this.loadBalanced\n            ? this.waitQueueErrorMetrics()\n            : 'Timed out while checking out a connection from connection pool',\n          this.address\n        );\n        if (options.timeoutContext.csotEnabled()) {\n          throw new MongoOperationTimeoutError('Timed out during connection checkout', {\n            cause: timeoutError\n          });\n        }\n        throw timeoutError;\n      }\n      throw error;\n    } finally {\n      abortListener?.[kDispose]();\n      timeout?.clear();\n    }\n  }\n\n  /**\n   * Check a connection into the pool.\n   *\n   * @param connection - The connection to check in\n   */\n  checkIn(connection: Connection): void {","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/cmap/connection_pool.ts#L348-L384","documentation":"A MongoOperationTimeoutError thrown in ConnectionPool.checkOut when CSOT is enabled and the wait-queue timeout fires before a connection becomes available. The underlying WaitQueueTimeoutError is attached as cause. Under CSOT the checkout timeout is derived from the operation's timeoutMS; when it expires, the driver raises this unified timeout error instead of the legacy WaitQueueTimeoutError.","triggerScenarios":"All connections are checked out and the operation's CSOT budget (timeoutMS) expires while waiting in the pool's wait queue. Triggered by sustained concurrency exceeding maxPoolSize under CSOT.","commonSituations":"maxPoolSize too low for the workload; long-running queries holding connections; connection leaks (connections not returned); spikes in concurrent requests under a tight timeoutMS.","solutions":["Increase maxPoolSize to match peak concurrency.","Increase timeoutMS to allow more wait time for a connection.","Audit for connection leaks — ensure cursors and sessions are closed/iterated to completion.","Reduce per-operation hold time (faster queries, indexes) so connections recycle faster."],"exampleFix":"// before\nconst client = new MongoClient(uri, { maxPoolSize: 5, timeoutMS: 1000 });\n\n// after\nconst client = new MongoClient(uri, { maxPoolSize: 50, timeoutMS: 10000 });","handlingStrategy":"retry","validationCode":"// Sanity check pool sizing vs. expected concurrency\nconst expectedConcurrency = 100;\nif (maxPoolSize < expectedConcurrency && timeoutMS < 5000) {\n  // either grow the pool or widen the timeout\n  maxPoolSize = expectedConcurrency;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await operation();\n} catch (e) {\n  if (e instanceof MongoOperationTimeoutError && /connection checkout/i.test(e.message)) {\n    // transient pool exhaustion — back off and retry\n  } else throw e;\n}","preventionTips":["Size maxPoolSize to peak concurrency.","Close cursors/sessions promptly to recycle connections.","Add indexes to shorten per-connection hold time."],"tags":["timeout","connection-pool","csot","pool-exhaustion"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}