MongoDB server selection timed out, explained and fixed

MongoDB drivers do not connect to one fixed server; they discover the deployment's topology and select a node matching the operation's requirements (a primary for writes, for instance). Server selection timed out after 30000 ms (in some drivers worded ServerSelectionError) means that discovery never produced a usable node within the timeout: every candidate was unreachable, rejected, or unsuitable. The message deliberately bundles several causes, and the driver's wrapped inner errors and the topology description it logs name which one, so the diagnosis is in the details the application may be swallowing.

The causes, in the order to check them

  1. The network path: for MongoDB Atlas, the client's IP address must be on the cluster's IP allowlist, the single most common cause of this error, especially when an application's egress IP changes (a new cloud region, a NAT gateway, a home connection). For self-hosted servers, the equivalents are the firewall or security group on port 27017 and whether the server binds beyond localhost.
  2. The connection string: a wrong host, a stale cluster address after a cloud migration, or a +srv string whose DNS SRV lookup fails or is filtered. Test the same string with mongosh from the same machine and network as the application; it prints precise DNS and connection errors the driver buries.
  3. Authentication and TLS mismatches: wrong credentials or a missing TLS requirement typically produce their own distinct errors, but some drivers surface them during selection; if the string and network verify, enable the driver's logging and read the per-server error it reports.
  4. The deployment genuinely has no suitable node: a replica set mid-election, all secondaries down while the read preference demands one, or a primary that stepped down. This is measured in seconds to a minute for elections; a persistent timeout with a healthy mongosh connection points back to the application's string or network instead.

Fixes and tuning, honestly scoped

  1. Fix the allowlist or firewall entry for the application's actual egress address, using the narrowest range that covers it; allowlisting 0.0.0.0/0 “to make it work” removes the control entirely and should only ever be a momentary diagnostic.
  2. Correct the connection string from the platform's own connect dialog (Atlas generates current strings per driver version), including the database and options segments applications often hand-edit wrongly.
  3. Adjust serverSelectionTimeoutMS only for genuinely slow starts (cold containers, distant regions). Raising it on an unreachable cluster changes nothing but how long each request waits before failing; the default 30 seconds is already generous.

Common questions

Why did it start after we deployed to a new environment? The application's network identity changed: new egress IPs meet an Atlas allowlist written for the old ones. It is the first thing to check after any hosting move, ahead of the connection string, which usually travels unchanged.

mongosh connects but the application times out, why? They are not using the same inputs: compare the exact connection string, the driver version's default options (some older drivers mishandle SRV or TLS defaults), and whether the application runs in a different network namespace (container, VPC) than the shell where mongosh succeeded.

Can I lower the timeout so failures surface faster? Yes, serverSelectionTimeoutMS is configurable and lowering it in user-facing paths is reasonable once connectivity is proven healthy. It changes failure latency, not failure likelihood.

Related errors

MySQL error 1040 (Too many connections) · MySQL error 2002 (cannot connect) · SQLite: database is locked