mongodb/node-mongodb-native · error · MongoUnexpectedServerResponseError

Unable to get response from server

Error message

Unable to get response from server

What it means

Thrown at the end of Connection.command() (src/cmap/connection.ts:661) when the async generator returned by sendCommand completes without yielding any document. The command() method expects at least one response frame; if the server closed the stream or returned nothing, the loop body never executed and this MongoUnexpectedServerResponseError fires as a safety net against returning undefined.

Source

Thrown at src/cmap/connection.ts:661

          }
        } else {
          if (
            (Array.isArray(document?.writeErrors) &&
              document.writeErrors.some(
                error => error?.code === MONGODB_ERROR_CODES.MaxTimeMSExpired
              )) ||
            document?.writeConcernError?.code === MONGODB_ERROR_CODES.MaxTimeMSExpired
          ) {
            throw new MongoOperationTimeoutError('Server reported a timeout error', {
              cause: new MongoServerError(document)
            });
          }
        }
      }

      return document;
    }
    throw new MongoUnexpectedServerResponseError('Unable to get response from server');
  }

  public exhaustCommand(
    ns: MongoDBNamespace,
    command: Document,
    options: CommandOptions,
    replyListener: Callback
  ) {
    const exhaustLoop = async () => {
      this.throwIfAborted();
      for await (const reply of this.sendCommand(ns, command, options)) {
        replyListener(undefined, reply);
        this.throwIfAborted();
      }
      throw new MongoUnexpectedServerResponseError('Server ended moreToCome unexpectedly');
    };

    exhaustLoop().then(undefined, replyListener);

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Enable retryable reads/writes (retryWrites=true, retryReads=true - default on) so transient single-connection failures are retried on a fresh connection.
  2. Raise maxIdleTimeMS or configure keepalive so LBs do not drop idle connections.
  3. Check server logs for restarts or crashes around the error time.
  4. Reduce connection pool idle time or use minPoolSize to keep connections warm.

Example fix

// before
new MongoClient(uri, { retryWrites: false, maxIdleTimeMS: 30 });

// after
new MongoClient(uri, { retryWrites: true, maxIdleTimeMS: 60000, minPoolSize: 1 });
Defensive patterns

Strategy: retry

Validate before calling

function poolWarmOptions() {
  return { retryWrites: true, retryReads: true, minPoolSize: 1, maxIdleTimeMS: 60000 };
}

Type guard

import { MongoUnexpectedServerResponseError } from 'mongodb';
function isEmptyStreamError(e: unknown): e is MongoUnexpectedServerResponseError {
  return e instanceof MongoUnexpectedServerResponseError &&
    /Unable to get response/.test(e.message);
}

Try / catch

import { MongoUnexpectedServerResponseError } from 'mongodb';
async function resilientFind(coll: any, q: any, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    try { return await coll.findOne(q); }
    catch (e) {
      if (e instanceof MongoUnexpectedServerResponseError && i < attempts - 1) continue;
      throw e;
    }
  }
}

Prevention

When it happens

Trigger: The server or network closed the socket between sending the command and reading the reply, but in a way that did not surface as an explicit error - the read stream simply ended cleanly with zero frames. Internal to command() at src/cmap/connection.ts:636-661.

Common situations: Connection killed by an idle-timeout LB (Azure, AWS NLB) between write and read; server process restarted mid-command; TLS handshake completed but the server sent RST without payload; proxy that returns empty on upstream close; race between pool pruning and command dispatch.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04). Data as JSON: /data/errors/90d58a83dacef03e.json. Report an issue: GitHub.