Что означает ошибка EADDRINUSE
Сообщение Error: Address already in use (или EADDRINUSE, listen EADDRINUSE: address already in use) возникает, когда приложение пытается привязаться к сетевому порту, который уже прослушивается другой программой. В TCP/IP-стеке один IP-адрес и порт могут быть назначены только одному процессу одновременно. Если сокет уже занят, операционная система отклоняет запрос на запуск, чтобы избежать конфликтов маршрутизации входящего трафика. Чаще всего вы столкнётесь с этой проблемой при запуске локальных серверов разработки, баз данных (MySQL, PostgreSQL), прокси-серверов или контейнеров Docker.
Причины возникновения
- Конфликт с системным сервисом. Стандартные порты (80, 443, 3306, 5432) часто заняты веб-серверами, базами данных или утилитами вроде IIS и Apache.
- Зависший фоновый процесс. Приложение могло аварийно завершиться, но его процесс остался в памяти и не освободил сетевой дескриптор.
- Состояние
TIME_WAIT. После закрытия соединения ОС временно резервирует порт (обычно на 1–4 минуты) для обработки оставшихся в буфере пакетов. - Параллельный запуск. Вы случайно запустили вторую копию того же приложения, и обе версии пытаются занять одинаковый порт.
Способы решения
Способ 1: Диагностика через терминал
Первым делом нужно узнать, какой именно процесс блокирует порт. Откройте командную строку или терминал и выполните команду, подходящую для вашей ОС. Замените 8080 на номер вашего порта.
Windows (PowerShell / CMD от имени администратора):
netstat -ano | findstr :8080
Результат покажет статус LISTENING и PID (последняя колонка). Запомните этот номер.
Linux / macOS:
sudo lsof -i :8080
# или
sudo ss -tulpn | grep :8080
Команда выведет имя процесса и его PID в колонке PID/Program name.
Способ 2: Безопасное завершение блокирующего процесса
Получив идентификатор процесса, его можно принудительно остановить.
⚠️ Важно: Убедитесь, что завершаемый процесс не является критичным системным компонентом (например,
svchost.exeилиsystemd-resolved). Остановка таких служб может нарушить работу сети.
Windows:
taskkill /PID 1234 /F
Флаг /F гарантирует принудительное завершение даже при зависании.
Linux / macOS:
kill -9 1234
Если сервис управляется менеджером процессов, лучше использовать штатные команды: sudo systemctl stop <имя_сервиса>.
Способ 3: Переназначение порта в конфигурации
Если освободить порт невозможно или он нужен другой критичной программе, измените настройку прослушивания в вашем приложении.
- Откройте конфигурационный файл (например,
docker-compose.yml,.env,config.jsonилиserver.js). - Найдите параметр
port,PORTилиLISTEN_PORT. - Замените значение на свободное (например,
8081или3001). - Перезапустите приложение.
Для большинства Node.js/Python-проектов достаточно задать переменную окружения перед запуском:
export PORT=3001 && node server.js # Linux/macOS
set PORT=3001 && node server.js # Windows CMD
$env:PORT="3001"; node server.js # Windows PowerShell
Профилактика
Чтобы избежать повторения ошибки, придерживайтесь следующих правил:
- Используйте динамическое выделение. Для локальной разработки настраивайте приложения на автоматический выбор свободного порта (флаги
--port 0или конфигурацияport: "auto"). - Корректно обрабатывайте завершение. В коде сервера обязательно привязывайте обработчик сигналов
SIGINT/SIGTERM, который корректно закрывает соединения (server.close()), а не просто обрывает процесс. - Проверяйте порты перед деплоем. Добавьте в скрипты запуска предварительную проверку занятости порта через
nc -z localhost <порт>или PowerShell-аналогTest-NetConnection. - Изолируйте среды. Запускайте проекты в Docker-контейнерах с пробросом портов (
-p 8080:3000), чтобы избежать конфликтов на хост-машине.