MongoServerSelectionError: por qué MongoDB no conecta

MongoServerSelectionError significa que el driver no encontró ningún servidor MongoDB disponible dentro del plazo, 30 segundos por defecto. Las causas más comunes son host incorrecto, servidor detenido, firewall o lista de IP y DNS.

Actualizado el 8 min de lectura

Objetivos de aprendizaje

Después de leer este artículo podrás:

  • Leer el mensaje de MongoServerSelectionError y saber qué indica cada parte
  • Diagnosticar la causa con un script corto, mongosh y pruebas de red
  • Corregir host, firewall, lista de IP, DNS, TLS y replica set
En esta página

Inicias la aplicación, se queda colgada unos segundos y luego falla con MongoServerSelectionError. El nombre asusta, pero el mensaje dice algo simple: el driver buscó un servidor MongoDB con el que hablar y no encontró ninguno que respondiera a tiempo. La conexión ni siquiera empezó, así que no sirve de nada tocar consultas, índices o esquemas.

Los ejemplos de abajo usan el driver oficial mongodb para Node.js y valen también para Mongoose, que usa ese driver por debajo. Si todavía estás armando la conexión desde cero, empieza por cómo conectar MongoDB a Node.js.

serverSelectionTimeoutMSLee la cadenalista de hosts1Resuelve el DNScada nombre2ENOTFOUNDel nombre no resuelveAbre TCP y TLScon cada host3ECONNREFUSEDo firewall en silencioPregunta el papelprimario o secundario4ReplicaSetNoPrimarynombres internosMongoServerSelectionErrorningún host sirvió a tiempo
El error dice que ningún host pasó todas las etapas antes del plazo; la etapa que falló indica la causa.

¿Cómo es el mensaje de error?#

Lo que importa es el texto después de los dos puntos. Estos son mensajes reales del driver:

MongoServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
MongoServerSelectionError: connect ECONNREFUSED ::1:27017, connect ECONNREFUSED 127.0.0.1:27017
MongoServerSelectionError: getaddrinfo ENOTFOUND db.ejemplo.internal
MongoServerSelectionError: Server selection timed out after 30000 ms

Cada uno apunta a un lugar distinto:

  • ECONNREFUSED: la dirección existe, pero nada aceptó la conexión en ese puerto. El servidor está detenido, escucha en otra interfaz o estás en el host equivocado.
  • ENOTFOUND: el nombre del host no se resolvió en el DNS. Un error de tipeo, un nombre interno que solo existe en otra red o una variable de entorno con un valor viejo.
  • Server selection timed out: los paquetes salieron y no volvió nada. Es el patrón de un firewall, una lista de IP que bloquea o una dirección inalcanzable.

En Mongoose el error se llama MongooseServerSelectionError. Cuando el destino es un clúster de MongoDB Atlas y ningún servidor responde, cambia el mensaje por este:

MongooseServerSelectionError: Could not connect to any servers in your MongoDB Atlas cluster. One common reason is that you're trying to access the database from an IP that isn't whitelisted. Make sure your current IP address is on your Atlas cluster's IP whitelist: https://www.mongodb.com/docs/atlas/security-whitelist/

En Python, el equivalente de PyMongo es pymongo.errors.ServerSelectionTimeoutError, con la descripción de la topología al final del mensaje.

¿Qué intenta hacer el driver antes de rendirse?#

El driver no abre una conexión y listo. Lee la lista de hosts de la cadena de conexión, resuelve cada nombre en el DNS, abre TCP (y TLS, si está activado) con cada uno y le pregunta al servidor cuál es su papel: primario, secundario o servidor aislado. Solo entonces elige un servidor adecuado para la operación. Ese proceso es la selección de servidor.

Si ningún host sirve dentro de serverSelectionTimeoutMS, la operación falla. El valor por defecto es 30000 ms, por eso el error suele aparecer medio minuto después. En los replica sets hay una regla más: los nombres de host de la cadena deben coincidir con los de la configuración del replica set, y el driver tiene que poder alcanzar a los miembros por esos nombres. Los términos se explican en collections, clusters y replica sets.

Dos consecuencias prácticas: el error dice poco sobre la base de datos en sí, y acortar el plazo ayuda a diagnosticar. Con serverSelectionTimeoutMS: 5000, esperas 5 segundos en lugar de 30 en cada intento.

¿Cómo diagnosticar la causa?#

Empieza por el propio driver. El error trae en reason la topología que vio, con el estado de cada host. Este script lo imprime todo:

javascript
// diagnostico.mjs
import { MongoClient } from "mongodb";

const uri = process.env.MONGODB_URI;
if (!uri) throw new Error("Define la variable MONGODB_URI");

const client = new MongoClient(uri, { serverSelectionTimeoutMS: 5000 });

try {
  await client.db("admin").command({ ping: 1 });
  console.log("Conectado: el servidor respondió al ping");
} catch (error) {
  console.error(`${error.name}: ${error.message}`);
  // error.reason describe la topología que vio el driver
  console.error("Topología:", error.reason?.type);
  for (const [host, servidor] of error.reason?.servers ?? []) {
    console.error(`- ${host}: ${servidor.type} ${servidor.error?.message ?? ""}`);
  }
  process.exitCode = 1;
} finally {
  await client.close();
}

Ejecútalo con MONGODB_URI="mongodb://..." node diagnostico.mjs en la misma máquina donde falla la aplicación. Una topología ReplicaSetNoPrimary (o Unknown, cuando la cadena tiene un solo host) con todos los hosts en Unknown indica que ningún servidor respondió.

Después, separa la red de la aplicación con herramientas fuera de Node.js. Los tres comandos de abajo responden, en este orden: ¿el nombre se resuelve? ¿El puerto está abierto desde esta máquina? ¿El servidor responde con la misma cadena?

bash
nslookup db.ejemplo.com
nc -vz db.ejemplo.com 27017
mongosh "$MONGODB_URI" --eval "db.runCommand({ ping: 1 })"

En PowerShell, Test-NetConnection db.ejemplo.com -Port 27017 reemplaza a nc. Si mongosh también falla, el problema no está en tu código.

¿Por qué aparece ECONNREFUSED?#

De la causa más común a la menos común:

  1. La cadena apunta a localhost fuera de tu computadora. En tu PC había un MongoDB local; en el servidor o en el contenedor, localhost es esa misma máquina, donde no hay base de datos. Es el caso clásico de "funciona aquí, falla en producción". Revisa también si el código tiene un valor de respaldo como process.env.MONGODB_URI || "mongodb://localhost:27017": si la variable no está definida, cae en localhost sin avisar. Mira qué son las variables de entorno.
  2. El servidor está detenido. Revisa el proceso mongod o el contenedor de la base de datos y lee su log.
  3. El servidor solo escucha en localhost. Por defecto, mongod acepta conexiones solo en localhost. Para acceder desde otra máquina, debe escuchar en la interfaz de red correcta (net.bindIp), de preferencia la interna, detrás de un firewall y con autenticación.
  4. IPv6 frente a IPv4. En las versiones recientes de Node.js, localhost puede resolverse primero como ::1, y Node prueba las dos direcciones, por eso el mensaje lista ::1 y 127.0.0.1. Si la base de datos solo escucha en IPv4, usa 127.0.0.1 en la cadena o la opción family: 4.

Una conexión rechazada en otras bases de datos sigue la misma lógica: mira conexión rechazada en la base de datos.

¿Por qué se agota el tiempo de la selección de servidor?#

Un timeout significa que nadie respondió, ni siquiera para rechazar. Las causas típicas:

  • Lista de IP del proveedor. MongoDB Atlas solo acepta conexiones desde direcciones que están en la lista de acceso del proyecto. Agrega la IP pública desde la que sale tu aplicación. Las IP residenciales cambian con el tiempo, así que un acceso que funcionaba ayer puede dejar de funcionar hoy.
  • Firewall. El puerto (27017 por defecto) está cerrado en el servidor de la base de datos, en el grupo de seguridad de la nube o en la red de salida de tu aplicación. Abre solo el puerto de la base de datos y solo para quien lo necesita.
  • Replica set con nombres internos. El driver se conecta al primer host, recibe la lista de miembros con nombres que solo existen dentro de la red de la base de datos (como nombres de contenedores) y no logra alcanzarlos. La topología queda en ReplicaSetNoPrimary. Corrige los nombres en la configuración del replica set o, para probar un solo miembro, usa directConnection=true.
  • TLS que no coincide. Si el servidor exige TLS y el cliente no lo usa (o al revés), la negociación inicial no se completa y el driver puede esperar hasta el final del plazo. Mira la siguiente sección.

¿Y si el error tiene que ver con DNS o TLS?#

Las cadenas mongodb+srv:// no listan hosts. El driver busca un registro SRV y un registro TXT en el DNS para descubrir los servidores y las opciones. Cuando esa búsqueda falla, el error aparece antes de la selección, con otro texto:

Error: querySrv ENOTFOUND _mongodb._tcp.cluster0.ejemplo.mongodb.net

Revisa el nombre del clúster que copiaste del proveedor y prueba la resolución con nslookup -type=SRV _mongodb._tcp.cluster0.ejemplo.mongodb.net. Algunos DNS de proveedores de internet y de VPN fallan con registros SRV; cambiar el resolvedor de la máquina suele resolverlo. Para entender el camino de la consulta, lee qué es el DNS.

Con mongodb+srv://, TLS se activa automáticamente. Con mongodb://, viene desactivado (tls=false) y tienes que agregar tls=true si el servidor lo exige. Los servidores con certificado propio necesitan tlsCAFile apuntando a la autoridad certificadora. En Mongoose, un mensaje que habla de SSL indica justamente ese desajuste. Lo básico de los certificados está en qué es SSL/TLS.

¿Cómo evitar que el error vuelva?#

  • Falla temprano. Haz un ping al iniciar y termina el proceso con un mensaje claro si falla, en vez de dejar que cada petición espere 30 segundos.
  • Valida la variable. Detén la aplicación si MONGODB_URI está vacía, sin valor de respaldo hacia localhost.
  • Usa un solo cliente. Un MongoClient por proceso, reutilizado en todo. Crear un cliente por petición agota las conexiones y genera otros errores, como too many connections.
  • No abras la base de datos al mundo. Permitir 0.0.0.0/0 hace desaparecer el error, pero expone la base de datos a cualquier dirección. Prefiere la red interna o la IP de salida de la aplicación.

Cómo hacerlo en Square Cloud#

Square Cloud ofrece hosting de MongoDB a partir del plan Standard (el Hobby no incluye bases de datos). La base de datos queda lista en segundos, en el mismo datacenter que las aplicaciones, con una latencia media de alrededor de 1 ms. Es un nodo único (standalone, sin replica set) y exige TLS. Esos dos puntos son los que más explican este error aquí.

Para evitar las causas más comunes:

  1. Copia la URL de conexión completa que te entrega el panel y no añadas replicaSet: en un nodo único, ese parámetro hace que el driver espere un primario que no existe.
  2. Descarga el certificado en el panel y pasa tls: true, tlsCAFile con la CA y tlsCertificateKeyFile con el .pem, porque el cliente también presenta el certificado.
  3. Define MONGODB_URI como variable de entorno de la aplicación, en el panel, la API, la CLI o VS Code. El cambio vale en el próximo reinicio, así que reinicia la aplicación después de editar la variable.
  4. Usa un solo MongoClient en el código, sin valor de respaldo hacia localhost, y ejecuta el script de diagnóstico de arriba. La base acepta conexiones desde fuera, así que el script también corre en tu máquina.

Si tu aplicación usa un MongoDB de otro proveedor con lista de IP, recuerda que sale por una IPv4 dinámica, sin una IP fija que permitir. Para recuperar datos, puedes tomar snapshots manuales cuando quieras, y todo plan que incluye bases de datos tiene también un snapshot automático diario. Puedes restaurar un snapshot en la misma base, en otra del mismo motor o en una base nueva. Mira los detalles en hosting de MongoDB.

Hosting de bases de datos

MongoDB, PostgreSQL, MySQL y Redis junto a tu app

Más información

Preguntas frecuentes

¿Qué es MongoServerSelectionError?

Es el error que lanza el driver de MongoDB cuando no logra elegir un servidor para la operación dentro de serverSelectionTimeoutMS. Indica que la conexión ni siquiera ocurrió, así que el problema está en la red, la dirección o el servidor.

¿Por qué el error aparece después de 30 segundos?

Porque el valor por defecto de serverSelectionTimeoutMS es 30000 ms. El driver intenta descubrir los servidores durante ese tiempo y solo se rinde al final. Puedes reducir el valor para que el error aparezca antes.

Funciona en mi computadora, pero no en el servidor. ¿Por qué?

Casi siempre la cadena de conexión apunta a localhost o la variable de entorno no se definió en el servidor. En otra máquina, localhost es esa misma máquina, donde no hay MongoDB corriendo.

¿Permitir 0.0.0.0/0 en MongoDB Atlas lo resuelve?

Quita el bloqueo por IP, pero el clúster pasa a aceptar conexiones desde cualquier dirección, protegido solo por usuario y contraseña. Es mejor permitir solo la IP de salida del servidor donde corre tu aplicación.

¿Una contraseña incorrecta causa MongoServerSelectionError?

En general, no. Un usuario o una contraseña incorrectos suelen generar un MongoServerError con Authentication failed. Si el error es de selección de servidor, revisa primero la red, la dirección o el DNS.

Siguiente artículoECONNREFUSED: la base de datos rechaza la conexiónECONNREFUSED significa que nada escucha en el host y el puerto de la base de datos. Causas (servidor detenido, localhost, puerto, bind) y cómo corregir cada una.

Más en Bases de datos

Ver los 24 artículos