Як виправити помилку таймауту мережі MongoDB у з'єднанні Mongoose

Найважливіше виправлення — перестати сприймати кожен таймаут Mongoose як проблему з налаштуванням таймауту. Повідомлення на кшталт MongoServerSelectionError: connection timed out зазвичай означає, що драйвер MongoDB не зміг обрати придатний сервер до закінчення часу serverSelectionTimeoutMS. У поточній документації з усунення несправностей MongoDB зазначено, що типовими причинами є проблеми з мережевим з'єднанням, обмеження доступу за IP в Atlas, збої DNS SRV та конфігурація TLS. Збільшення таймауту може змусити додаток чекати довше, не виправляючи жодної з цих умов.

Замість цього використовуйте такий порядок дій: 1) визначте, який саме таймаут спрацював, 2) переконайтеся, що хост додатка може отримати доступ до MongoDB, 3) виправте рядок з'єднання або адресу, специфічну для середовища, і 4) налаштовуйте значення таймаутів лише після того, як буде підтверджено працездатність з'єднання. Наведені нижче приклади використовують сучасні шаблони з'єднання Mongoose та поточну поведінку драйвера MongoDB, задокументовану у вересні 2026 року.

Спершу визначте, з яким саме таймаутом ви маєте справу

Mongoose використовує драйвер MongoDB для Node.js, тому в одній конфігурації з'єднання можуть зустрічатися різні налаштування таймаутів. Вони не означають одного й того ж.

Налаштування або симптомЩо він контролюєПоточне задокументоване значення за замовчуваннямТипова інтерпретація
serverSelectionTimeoutMSЯк довго драйвер намагається знайти придатний сервер MongoDB30 000 мсТопологія, DNS, брандмауер, доступ за IP, недоступний сервер або відсутність придатного primary/secondary
connectTimeoutMSЯк довго може тривати одна спроба встановлення TCP-з'єднання30 000 мс у поточному драйвері Node.jsХост/порт недоступний, фільтрується або занадто повільний для встановлення TCP
socketTimeoutMSЯк довго вже встановлене сокетне з'єднання може залишатися неактивним під час надсилання/отримання даних перед таймаутом0, що означає відсутність таймауту сокета в поточному драйвері Node.jsЗазвичай актуально після встановлення з'єднання, особливо для тривалих або завислих операцій
ETIMEDOUT / таймаут з'єднанняСимптом збою на мережевому рівніНе є значенням конфігурації за замовчуваннямЧасто пов'язано з доступністю, брандмауером, маршрутизацією, ціллю DNS або недоступним сервером

У поточній документації Mongoose щодо з'єднань зазначено, що значення serverSelectionTimeoutMS за замовчуванням становить 30 секунд і застосовується як до початкового виклику mongoose.connect(), так і до подальших операцій, які потребують вибору сервера. Документація драйвера MongoDB для Node.js щодо параметрів з'єднання розрізняє це значення від connectTimeoutMS та socketTimeoutMS.

Редактор коду та термінал, що показують помилку MongooseServerSelectionError з ECONNRESET та таймаутом вибору сервера після 30000 мілісекунд

Таймаут вибору сервера — це симптом, який слід класифікувати першим; деталі помилки та її первинна причина корисніші, ніж негайне збільшення 30-секундного ліміту.

Крок 1: захопіть точну помилку Mongoose та її первинну причину

Почніть з мінімального з'єднання та логування достатньої кількості інформації, щоб розрізнити збої DNS, автентифікації, TLS та доступності:

import mongoose from 'mongoose';

try {
  await mongoose.connect(process.env.MONGODB_URI, {
    serverSelectionTimeoutMS: 5000
  });

  console.log('MongoDB connected');
} catch (err) {
  console.error(err);
  console.error('Reason:', err.reason);
  process.exit(1);
}

Значення 5 секунд вище є діагностичним вибором, а не рекомендацією для продакшену в кожному розгортанні. Mongoose зазначає, що зменшення serverSelectionTimeoutMS може забезпечити швидший зворотний зв'язок, але особливо застерігає від випадкового зменшення цього значення для наборів реплік, оскільки стандартне 30-секундне вікно може допомогти операціям пережити вибори та відмови. Mongoose радить коротші значення переважно для автономного MongoDB або безсерверних середовищ виконання, де швидка відмова є корисною.

Шукайте такі підказки:

  • getaddrinfo ENOTFOUND — не вдається розв'язати DNS-ім'я.
  • ECONNREFUSED — щось активно відхилило TCP-з'єднання, часто тому, що на хості/порті ніхто не очікує з'єднань.
  • ETIMEDOUT — спроба з'єднання не завершилася вчасно, часто через фільтрацію трафіку, неправильну маршрутизацію або недоступність призначення.
  • Текст про TLS або сертифікати — перевірте довіру до сертифіката, відповідність імені хоста, підтримку протоколу або конфігурацію TLS.
  • Помилки автентифікації всередині err.reason — виправте облікові дані або authSource, а не змінюйте мережеві таймаути.

Умова: якщо помилка вже вказує на збій автентифікації, пропустіть налаштування брандмауера, доки облікові дані та база даних автентифікації не будуть правильними. Таймаут мережі та відхилений вхід — це різні класи збоїв.

Крок 2: перевірте мережу, доступ за IP в Atlas та DNS з того самого середовища виконання

Запускайте тести з'єднання з тієї ж машини, контейнера, віртуальної машини, безсерверної функції або пода Kubernetes, де працює процес Node.js. Тестування з вашого ноутбука недостатньо, якщо продакшен працює в іншому місці.

Порада з усунення несправностей, що стверджує: MongoDB Atlas вимагає додавання IP додатка до списку дозволів, а локальний MongoDB має бути доступним на налаштованому порту

Для Atlas переконайтеся, що реальний вихідний IP додатка дозволений; для локального розгортання переконайтеся, що процес MongoDB дійсно очікує з'єднання на очікуваному інтерфейсі та порту.

Якщо ви використовуєте MongoDB Atlas

Atlas приймає з'єднання від клієнтів лише з адрес, дозволених у списку доступу за IP проєкту. MongoDB документує це в розділі Керування списком доступу за IP. Переконайтеся, що публічний вихідний IP середовища додатка доданий до списку, а не лише IP вашої особистої робочої станції.

У посібнику з усунення несправностей таймауту вибору сервера MongoDB також рекомендує перевіряти вихідну TCP-з'єднаність з MongoDB на порту 27017, а також брандмауери, групи безпеки, мережеві ACL, VPN та проксі-сервери.

Наприклад, з Linux або macOS ви можете перевірити конкретний вузол Atlas або керований вами хост за допомогою:

nc -vz your-mongodb-host.example.com 27017

У Windows PowerShell грубий тест доступності TCP виглядає так:

Test-NetConnection your-mongodb-host.example.com -Port 27017

Успішний тест TCP не гарантує успіху автентифікації або TLS, але невдалий тест TCP означає, що налаштування таймаутів Mongoose є передчасним.

Якщо ваш URI використовує mongodb+srv://

Рядок з'єднання SRV залежить від записів DNS SRV. Поточні кроки з усунення несправностей MongoDB рекомендують перевіряти пошук SRV з середовища клієнта:

nslookup -type=SRV _mongodb._tcp.cluster-name.mongodb.net

Якщо запит SRV не вдається, перевірте ім'я хоста та конфігурацію DNS. MongoDB документує рядок з'єднання mongodb:// без SRV як можливий обхідний шлях, коли середовище не може розв'язати записи SRV, але ви повинні отримати цей стандартний рядок з'єднання з Atlas або вашої конфігурації розгортання, а не вигадувати імена вузлів. Див. Усунення несправностей з'єднання в Atlas.

Діагностичний блок, що узагальнює перевірку рядка з'єднання, доступу за IP, брандмауера або VPN та параметрів таймауту Mongoose для таймауту MongoDB

Правильна послідовність діагностики перевіряє адресу та мережевий шлях, перш ніж вважати значення таймаутів першопричиною.

Крок 3: виправте URI для середовища, де насправді працює Node.js

Синтаксично правильний URI MongoDB все ще може вказувати не туди. Перевірте схему, ім'я хоста, порт, ім'я бази даних, вимоги до набору реплік, джерело автентифікації та чи є ім'я хоста значущим у мережевому просторі імен додатка.

Локальний Node.js та локальний MongoDB

Mongoose наразі рекомендує використовувати 127.0.0.1 замість localhost для локального MongoDB:

await mongoose.connect('mongodb://127.0.0.1:27017/myapp');

Причина полягає в Node.js 18 та новіших версіях: Mongoose зазначає, що Node.js може розв'язати localhost в IPv6 ::1, тоді як локальний екземпляр MongoDB може очікувати з'єднання лише на IPv4. Mongoose також документує { family: 4 } як опцію, коли пріоритетне розв'язання IPv6 уповільнює спроби з'єднання:

await mongoose.connect('mongodb://localhost:27017/myapp', {
  family: 4
});

Використовуйте family: 4 лише тоді, коли шлях розв'язання IPv4/IPv6 дійсно є проблемою. Якщо ваше розгортання MongoDB правильно підтримує IPv6, примусове використання IPv4 є непотрібним.

Node.js всередині Docker

Якщо додаток працює всередині контейнера, localhost посилається на цей контейнер, а не автоматично на MongoDB на хості або в іншому контейнері. Використовуйте ім'я хоста служби/контейнера MongoDB у спільній мережі Docker або специфічну для платформи адресу хоста, якщо MongoDB працює на хості.

Наприклад, для служби Compose з іменем mongo:

MONGODB_URI=mongodb://mongo:27017/myapp

Умова: цей приклад застосовний лише якщо контейнери спільно використовують мережу, а служба MongoDB дійсно називається mongo. Не копіюйте ім'я хоста в несумісне розгортання.

Atlas

Використовуйте рядок з'єднання, згенерований Atlas для вашого драйвера, збережіть хост mongodb+srv:// точно таким, закодуйте зарезервовані символи в іменах користувачів або паролях у форматі URL, якщо це необхідно, та переконайтеся, що користувач бази даних існує в потрібному проєкті.

Якщо ви підключаєтеся до керованого набору реплік, імена хостів, які повідомляє набір реплік, також мають бути доступними з клієнта. Початковий хост може бути доступним, але подальший вибір сервера все одно може зазнати невдачі, тому що члени набору реплік оголошують імена хостів, які додаток не може розв'язати або маршрутизувати.

Крок 4: налаштовуйте таймаути лише після успішного встановлення з'єднання

Якщо DNS розв'язується, мережевий шлях працює, сервер доступний, а URI правильний, тоді налаштування таймаутів стає змістовним.

Приклад з'єднання JavaScript Mongoose, що показує параметри serverSelectionTimeoutMS, socketTimeoutMS, connectTimeoutMS та retryWrites

Mongoose передає параметри з'єднання, пов'язані з таймаутами, базовому драйверу MongoDB, але кожен параметр контролює різний етап; більші значення не слід використовувати для приховування зламаної маршрутизації або недоступного сервера.

Консервативний приклад для додатка, який хоче отримати сигнал про невдачу протягом 10 секунд на початку, може виглядати так:

await mongoose.connect(process.env.MONGODB_URI, {
  serverSelectionTimeoutMS: 10000,
  connectTimeoutMS: 10000
});

Чи є 10 секунд доречним, залежить від розгортання. Компроміс є прямим:

ВибірПеревагаКомпромісДе це може бути доречним
Коротший таймаут вибору сервераШвидка відмова та швидший зворотний зв'язок при запускуМенше часу на переживання тимчасових змін топології або виборів у наборі реплікРозробка, перевірки стану, деякі шляхи запуску безсерверних додатків, автономний MongoDB
Стандартні 30 секундБільша толерантність до тимчасових порушень топології або мережіНеправильна конфігурація може виявлятися протягом 30 секундБагато загальних продакшн-розгортань та набори реплік
Довший таймаут вибору сервераБільше терпіння до незвично повільного відновленняЗапити та запуск можуть зависати довше перед відмовоюЛише коли виміряна поведінка відновлення виправдовує це

Для socketTimeoutMS поточна документація драйвера MongoDB для Node.js використовує значення за замовчуванням 0, що означає відсутність таймауту неактивності сокета. MongoDB рекомендує, коли ви вирішуєте встановити це значення, обрати значення приблизно в два-три рази довші за найповільнішу операцію, яку ви очікуєте. Це налаштування застосовується до сокетів, які вже встановили з'єднання, тому воно не є основним виправленням для початкового таймауту вибору сервера.

Не копіюйте старі параметри з'єднання Mongoose у поточний проєкт

Багато старих прикладів все ще містять useNewUrlParser, useUnifiedTopology, keepAlive або keepAliveInitialDelay. Поточний Mongoose не потребує старих опцій парсера/топології, а Mongoose документує keepAlive як увімкнений за замовчуванням з Mongoose 5.2 та застарілий як параметр з'єднання з версії 7.2.

Сучасна базова конфігурація навмисно мінімальна:

import mongoose from 'mongoose';

await mongoose.connect(process.env.MONGODB_URI);

Додавайте параметри з'єднання тому, що ваше середовище їх потребує, а не тому, що вони з'явилися у фрагменті коду п'ятирічної давнини.

Що робити, якщо з'єднання працює, але запити пізніше завершуються таймаутом?

Це інша проблема. Якщо mongoose.connect() завершується успішно, а додаток пізніше зависає на запитах, дослідіть затримку операцій, тиск на пул з'єднань, навантаження сервера, індекси та таймаути сокетів або операцій. Поточний драйвер MongoDB для Node.js розрізняє:

  • serverSelectionTimeoutMS — пошук придатного сервера.
  • connectTimeoutMS — встановлення одного TCP-з'єднання.
  • socketTimeoutMS — неактивність на встановленому сокеті.
  • maxTimeMS — обмеження часу виконання операції на сервері після її досягнення MongoDB.

Якщо зазнають невдачі лише довгі запити, збільшення serverSelectionTimeoutMS навряд чи вирішить справжню проблему.

Швидка діагностика за умовою помилки

Спостережувана умоваНайкорисніша наступна перевірка
Server selection timed out after 30000 msПеревірте err.reason, потім протестуйте топологію, DNS, доступність TCP, список доступу Atlas та TLS
getaddrinfo ENOTFOUNDПеревірте ім'я хоста та розв'язання DNS/SRV з середовища додатка
ECONNREFUSED 127.0.0.1:27017Переконайтеся, що MongoDB запущена та очікує з'єднання на цій адресі/порту; у Docker перевірте, чи не встановлено ім'я хоста неправильно як localhost
ETIMEDOUTПеревірте брандмауер, маршрутизацію, групи безпеки, список дозволів IP, VPN/проксі та доступність сервера
Помилка рукостискання TLS або сертифікатаВиправте ланцюг довіри, ім'я хоста, сертифікат або підтримувану конфігурацію TLS; не вимикайте перевірку як виправлення для продакшену
Збій автентифікаціїВиправте ім'я користувача, пароль, кодування URL, authSource або конфігурацію користувача бази даних
Локальне з'єднання повільне з localhostСпробуйте 127.0.0.1 або family: 4, якщо причиною є пріоритетне розв'язання IPv6

Шаблон з'єднання, придатний для продакшену

Тримайте секрети поза вихідним кодом, чітко повідомляйте про збій запуску, коли база даних недоступна, та логуєте достатньо деталей для діагностики без виведення облікових даних:

import mongoose from 'mongoose';

export async function connectDatabase() {
  const uri = process.env.MONGODB_URI;

  if (!uri) {
    throw new Error('MONGODB_URI is not set');
  }

  try {
    await mongoose.connect(uri, {
      serverSelectionTimeoutMS: 30000,
      connectTimeoutMS: 30000
    });

    console.log('MongoDB connected');
  } catch (err) {
    console.error('MongoDB connection failed:', err.message);
    console.error('Server selection reason:', err.reason);
    throw err;
  }
}

Ці 30-секундні значення відповідають поточним задокументованим значенням за замовчуванням, тому ви можете опустити їх, якщо явне зазначення політики не допомагає вашим операціям. Важлива частина — не числа; важливо знати, чому інше число було б кращим для вашого розгортання.

Фінальний чек-лист

  • Захопіть повну помилку та перевірте err.reason.
  • Переконайтеся, що розгортання MongoDB запущене та доступне.
  • Запустіть тести DNS та TCP з того самого середовища, де працює процес Node.js.
  • Для Atlas переконайтеся, що вихідний IP додатка доданий до списку доступу за IP.
  • Для mongodb+srv:// перевірте розв'язання DNS SRV.
  • Для локального MongoDB спробуйте 127.0.0.1, якщо localhost розв'язується в непридатний IPv6.
  • Для Docker або Kubernetes використовуйте ім'я хоста, яке є дійсним у цьому мережевому просторі імен.
  • Виправляйте помилки TLS або автентифікації замість того, щоб маскувати їх більшим таймаутом.
  • Налаштовуйте serverSelectionTimeoutMS, connectTimeoutMS або socketTimeoutMS лише для етапу, який вони дійсно контролюють.
  • Після виправлення переконайтеся, що додаток стабільно з'єднується з реального середовища розгортання, а не лише з ноутбука розробника.

Підсумок

Якщо Mongoose повідомляє про таймаут мережі MongoDB, спершу доведіть, що драйвер може виявити та отримати доступ до придатного сервера MongoDB. Обмеження IP в Atlas, брандмауери, розв'язання DNS SRV, неправильні імена хостів контейнерів, невідповідності IPv4/IPv6, недоступні процеси MongoDB та конфігурація TLS можуть створити враження, що 30-секундний таймаут є проблемою, хоча таймер лише повідомляє про збій.

Використовуйте налаштування таймаутів, щоб визначити, як довго ваш додаток має чекати на відому справну систему, а не для компенсації зламаної шляху з'єднання. Коли доступність мережі та URI правильні, обирайте значення таймаутів, які відповідають вашій моделі доступності, поведінці відмови та очікуваній затримці операцій.

Залишити коментар

Як виправити помилку “Prisma Client Has Not Been Generated Yet”

Як виправити помилку “Prisma Client Has Not Been Generated Yet”

Виправте помилку незгенерованого Prisma Client, перевіривши генератор, схему, шлях виводу, імпорти, версії, налаштування монорепозиторію та кроки збірки під час розгортання.

Як виправити помилку SSL-сертифіката: не вдалося отримати локальний сертифікат емітента в Git

Як виправити помилку SSL-сертифіката: не вдалося отримати локальний сертифікат емітента в Git

Виправте помилку Git «не вдалося отримати локальний сертифікат емітента», визначивши механізм довіри, встановивши правильний ланцюжок ЦС та зберігаючи перевірку SSL увімкненою.

Як виправити помилку таймауту мережі MongoDB у з'єднанні Mongoose

Як виправити помилку таймауту мережі MongoDB у з'єднанні Mongoose

Виправте помилки таймауту мережі MongoDB у Mongoose, визначивши тип таймауту, перевіривши доступність Atlas або TCP, виправивши URI та налаштувавши таймаути лише за необхідності.

Як виправити помилку «Execution Policy Restricted» у Windows PowerShell

Як виправити помилку «Execution Policy Restricted» у Windows PowerShell

Виправте помилку обмеженої політики виконання PowerShell, перевіривши область дії та групову політику, а потім обравши RemoteSigned, Unblock-File або тимчасовий параметр сесії.

Як виправити помилку npm ERR! code ERESOLVE: конфлікт залежностей-партнерів

Як виправити помилку npm ERR! code ERESOLVE: конфлікт залежностей-партнерів

Виправте конфлікти залежностей-партнерів npm ERESOLVE, визначивши несумісний діапазон пакетів, узгодивши версії, використовуючи npm explain та npm ls, а також розглядаючи legacy-peer-deps або force лише як контрольовані резервні варіанти.

Як виправити помилку підключення Redis до 127.0.0.1:6379

Як виправити помилку підключення Redis до 127.0.0.1:6379

Виправте помилки відмови у підключенні Redis на 127.0.0.1:6379, перевіривши сервер, порт, мережу Docker, redis.conf, автентифікацію та TLS.

Як виправити внутрішню помилку 500 у серверних компонентах Next.js

Як виправити внутрішню помилку 500 у серверних компонентах Next.js

Виправте помилки 500 у серверних компонентах Next.js, аналізуючи логи сервера, перевіряючи запити даних та змінні середовища, обробляючи помилки та перевіряючи збірку для продакшену.

Як виправити помилку CrashLoopBackOff у Kubernetes у локальному Minikube

Як виправити помилку CrashLoopBackOff у Kubernetes у локальному Minikube

Діагностуйте та виправляйте помилку CrashLoopBackOff у Kubernetes у локальному Minikube, перевіряючи стан пода, попередні логи, причини завершення роботи, проби, конфігурацію, ліміти пам’яті та стан кластера.

Як виправити помилку «Docker Desktop Engine Stopped» у Windows 11

Як виправити помилку «Docker Desktop Engine Stopped» у Windows 11

Виправте помилку «Docker Desktop Engine Stopped» у Windows 11, перевіривши статус Docker, оновивши та перезавантаживши WSL 2, підтвердивши віртуалізацію та використавши діагностику перед скиданням налаштувань.

Як виправити помилку Uncaught ReferenceError: process is not defined у Vite

Як виправити помилку Uncaught ReferenceError: process is not defined у Vite

Виправте помилку 'process is not defined' у Vite, замінивши використання process.env у стилі Node.js, правильно налаштувавши змінні VITE_ та перевіривши залежності.