{"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/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/cmap/connection_pool.ts#L348-L384","documentation":"Thrown in ConnectionPool.checkOut (src/cmap/connection_pool.ts:365-369) when CSOT (timeoutMS) is enabled and the wait queue timed out waiting for a free connection. Without CSOT the same condition throws a plain WaitQueueTimeoutError; with CSOT the driver re-wraps it as MongoOperationTimeoutError so it composes correctly with the operation's overall timeout semantics.","triggerScenarios":"All connections in the pool are checked out and busy, the operation's timeoutMS budget expires while waiting in the pool's waitQueue, and timeoutContext.csotEnabled() is true. Triggered on any operation whose connection checkout races the per-op timeout.","commonSituations":"maxPoolSize too small for the workload's concurrency; long-running queries holding connections; spike in request rate saturating the pool; timeoutMS set lower than typical checkout wait time; connection leaks (checked-out connections never returned) shrinking the effective pool.","solutions":["Increase maxPoolSize to match peak concurrency.","Increase timeoutMS so the operation can survive brief pool contention.","Find and fix connection leaks - ensure cursors and sessions are always closed (return connections to the pool).","Tune maxConnecting (default 2) upward if the bottleneck is connection setup rather than steady-state usage."],"exampleFix":"// before\nnew MongoClient(uri, { maxPoolSize: 5, timeoutMS: 50 });\n\n// after\nnew MongoClient(uri, { maxPoolSize: 50, timeoutMS: 1000 });","handlingStrategy":"retry","validationCode":"function validatePoolCapacityForConcurrency(maxPoolSize: number, peakConcurrency: number, timeoutMS: number) {\n  if (maxPoolSize < peakConcurrency) {\n    console.warn(`maxPoolSize ${maxPoolSize} < peak concurrency ${peakConcurrency}; checkout waits likely`);\n  }\n}","typeGuard":"import { MongoOperationTimeoutError } from 'mongodb';\nfunction isCheckoutTimeout(e: unknown): e is MongoOperationTimeoutError {\n  return e instanceof MongoOperationTimeoutError &&\n    /connection checkout/i.test(e.message);\n}","tryCatchPattern":"import { MongoOperationTimeoutError } from 'mongodb';\nasync function withCheckoutRetry<T>(fn: () => Promise<T>, attempts = 3): Promise<T> {\n  for (let i = 0; i < attempts; i++) {\n    try { return await fn(); }\n    catch (e) {\n      if (e instanceof MongoOperationTimeoutError && /connection checkout/i.test(e.message) && i < attempts - 1) {\n        await new Promise(r => setTimeout(r, 50 * (i + 1))); continue;\n      }\n      throw e;\n    }\n  }\n  throw new Error('unreachable');\n}","preventionTips":["Size maxPoolSize to expected peak concurrency.","Always close cursors/sessions so connections return to the pool.","Audit for connection leaks with serverStatus connections metrics.","Raise timeoutMS if transient pool contention is expected."],"tags":["connection-pool","timeout","csot","pool-checkout"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}