Когда нейросеть работает, но приложение её «не видит»
Локальные нейросети стали заметно проще в запуске. Ollama поднимает API практически одной командой, LM Studio умеет работать как OpenAI-совместимый сервер, собственный RAG можно собрать на FastAPI, а MCP-серверы позволяют подключать к AI-агентам файлы, базы данных и внутренние сервисы.
Но вместе с локальной AI-инфраструктурой появилась очень характерная ошибка. Модель загружена, приложение вроде бы запущено, а клиент сообщает:
Connection refused ERR_CONNECTION_REFUSED [WinError 10061] No connection could be made because the target machine actively refused it Failed to connect to localhost port 11434 Такая ситуация часто возникает при подключении Python-приложения к Ollama, Open WebUI к локальному API, AI-агента к MCP-серверу, Docker-контейнера к модели на Windows или собственного интерфейса к FastAPI.
Главное: ERR_CONNECTION_REFUSED обычно означает не проблему самой нейросети и не ошибку промпта. Клиент попытался подключиться к определённому IP-адресу и порту, но на этой точке подключения никто не принял соединение либо оно было явно отклонено.
Что означает ERR_CONNECTION_REFUSED простыми словами
Представим, что локальная модель должна отвечать по адресу:
http://127.0.0.1:11434 Здесь:
127.0.0.1— текущий компьютер;11434— порт, на котором ожидается сервер;http— протокол подключения.
Ваш Python-скрипт, браузер или AI-клиент обращается к этому адресу. Если приложение действительно слушает порт 11434, соединение устанавливается. Если же сервис остановлен, запущен на другом порту или слушает другой сетевой интерфейс, клиент получает отказ.
Это отличается от таймаута. При ERR_CONNECTION_TIMED_OUT клиент долго ждёт ответа и не получает его. При ERR_CONNECTION_REFUSED отказ обычно приходит почти сразу.
Если ошибка возникает не в AI-инфраструктуре, а при обычном открытии веб-сайта, полезен отдельный разбор, где подробно объясняется код ошибки err connection refused, включая типовые причины на Windows, настройки прокси, DNS и серверную диагностику.
Почему эта ошибка особенно часто встречается при работе с локальным ИИ
Современный AI-проект редко состоит из одного процесса. Даже относительно простой локальный ассистент может выглядеть так:
React → Django/FastAPI → AI-agent → Ollama/LM Studio → векторная база → MCP-сервер
Каждая стрелка означает отдельное сетевое соединение. Если хотя бы один компонент:
- не запустился;
- изменил порт;
- работает внутри Docker;
- слушает только localhost;
- оказался внутри WSL;
- запущен на другом компьютере;
- попал под прокси или firewall;
цепочка перестаёт работать.
Поэтому диагностировать ошибку нужно не методом «перезагрузить всё», а последовательно: адрес → порт → процесс → интерфейс → сеть → приложение.
Шаг 1. Проверьте, действительно ли сервис запущен
Это звучит банально, но является одной из самых частых причин.
Например, приложение настроено на Ollama:
OLLAMA_BASE_URL=http://localhost:11434 Сначала попробуйте обратиться к серверу напрямую.
В PowerShell:
curl http://127.0.0.1:11434/api/tags Если Ollama работает, вы должны получить ответ API со списком моделей или другой корректный HTTP-ответ.
Если PowerShell сразу сообщает, что подключиться невозможно, проблема находится ниже уровня вашего AI-приложения. Пока этот URL не начал отвечать напрямую, бессмысленно искать ошибку в LangChain, OpenAI SDK или коде агента.
Шаг 2. Проверьте порт через PowerShell
На Windows удобно использовать Test-NetConnection.
Test-NetConnection 127.0.0.1 -Port 11434 Главная строка:
TcpTestSucceeded : True Если вместо True указано False, порт недоступен.
По этой проверке уже можно разделить проблему на две категории.
| Результат | Что означает |
|---|---|
TcpTestSucceeded: True | Сетевое соединение возможно. Нужно проверять URL API, endpoint, авторизацию и код клиента. |
TcpTestSucceeded: False | Сначала проверяйте запущенный процесс, порт, bind-адрес, Docker и сетевые правила. |
Шаг 3. Узнайте, слушает ли кто-нибудь нужный порт
На Windows можно выполнить:
netstat -ano | findstr :11434 Если сервис работает, вы увидите что-то похожее:
TCP 127.0.0.1:11434 0.0.0.0:0 LISTENING 18432 Последнее число — PID процесса.
Узнать, какое приложение использует этот PID:
tasklist /FI "PID eq 18432" Или через PowerShell:
Get-Process -Id 18432 Если netstat вообще ничего не показывает, почти наверняка сервер не запущен либо использует другой порт.
Какие порты часто встречаются в AI-проектах
Значения зависят от настроек, но типичные локальные конфигурации выглядят примерно так:
| Инструмент | Часто используемый порт | Пример адреса |
|---|---|---|
| Ollama | 11434 | http://localhost:11434 |
| LM Studio API | 1234 | http://localhost:1234/v1 |
| FastAPI / Uvicorn | 8000 | http://localhost:8000 |
| Django development server | 8000 | http://127.0.0.1:8000 |
| Frontend dev server | 3000 / 5173 | http://localhost:5173 |
Это не гарантированные значения. Любой из этих портов можно изменить, поэтому проверяйте фактические настройки своего приложения.
Одна из самых коварных причин: 127.0.0.1 и 0.0.0.0
Представим FastAPI-приложение:
uvicorn app:app --host 127.0.0.1 --port 8000 Оно доступно только через loopback-интерфейс текущей системы.
Для браузера на том же компьютере это нормально. Но контейнер Docker, другой компьютер или виртуальная машина обратиться к нему напрямую уже не смогут.
Для доступа извне сервер обычно запускают так:
uvicorn app:app --host 0.0.0.0 --port 8000 0.0.0.0 — это адрес привязки сервера, а не адрес, который обычно вводят в браузере. Для подключения используйте реальный IP машины, 127.0.0.1 или доменное имя в зависимости от схемы сети.
ERR_CONNECTION_REFUSED в Docker: localhost означает не то, что кажется
Одна из самых распространённых ошибок при сборке AI-stack через Docker выглядит так.
На Windows запущена Ollama:
http://localhost:11434 В контейнере запускается Python-приложение:
OLLAMA_BASE_URL=http://localhost:11434 И оно получает connection refused.
Причина в том, что localhost внутри контейнера — это сам контейнер, а не ваш Windows-компьютер.
В Docker Desktop для обращения к хосту часто используют:
http://host.docker.internal:11434 Схема становится такой:
Docker-контейнер → host.docker.internal → Windows → Ollama
Если же сервер находится в другом контейнере одного Docker Compose-проекта, обычно обращаться нужно по имени сервиса.
Например:
services: api: ... ollama: ... # из контейнера api: OLLAMA_BASE_URL=http://ollama:11434 То есть внутри Docker Compose имя сервиса фактически становится сетевым именем.
Не забудьте пробросить порт контейнера
Есть противоположная ситуация: сервер работает внутри Docker, а обратиться к нему нужно с Windows.
Если приложение внутри контейнера слушает порт 8000, одного этого недостаточно.
Нужно опубликовать порт:
docker run -p 8000:8000 my-ai-api И сам сервер внутри контейнера должен слушать не только 127.0.0.1:
uvicorn app:app --host 0.0.0.0 --port 8000 Для Docker Compose:
services: api: ports: - "8000:8000" После этого запрос с Windows:
curl http://localhost:8000 должен доходить до контейнера.
Почему AI-агент не подключается к MCP-серверу
С MCP ситуация очень похожа. Допустим, агент ожидает HTTP-сервер:
http://127.0.0.1:8765 Но MCP-сервер:
- не запущен;
- упал при старте;
- использует другой транспорт;
- слушает иной порт;
- работает внутри WSL или Docker;
- запущен через stdio, хотя клиент ожидает HTTP.
Важно сначала понять транспорт.
Некоторые MCP-серверы работают через обычные stdin/stdout и вообще не открывают сетевой порт. В этом случае попытка обратиться к ним через localhost концептуально неверна.
Поэтому при диагностике MCP всегда проверяйте:
- какой транспорт использует сервер;
- кто запускает процесс;
- какой URL ожидает клиент;
- доступен ли порт;
- не завершился ли процесс сразу после старта.
LM Studio запущен, но API всё равно недоступен
Наличие загруженной модели в LM Studio ещё не означает, что запущен локальный API-сервер.
Это разные состояния:
- модель загружена в интерфейс;
- модель готова к чату;
- локальный API Server запущен;
- API слушает нужный порт;
- API разрешает подключения с нужного интерфейса.
Если приложение настроено на:
http://localhost:1234/v1 проверьте непосредственно endpoint:
curl http://localhost:1234/v1/models Если этот запрос не работает, OpenAI SDK тем более не сможет подключиться.
Отделяйте сетевую ошибку от ошибки API
Это сильно ускоряет диагностику.
| Ошибка | Что обычно означает |
|---|---|
| Connection refused | Соединение с портом не установлено |
| 404 Not Found | Сервер доступен, но указан неправильный endpoint |
| 401 Unauthorized | Сервер работает, но требуется корректная авторизация |
| 403 Forbidden | Сервер понял запрос, но запрещает действие |
| 500 Internal Server Error | Соединение работает, ошибка уже внутри приложения |
| Timeout | Ответ не пришёл за установленное время |
Если вы получили HTTP 404 или 500, сеть уже работает. Не нужно продолжать перестраивать firewall и менять DNS — ищите ошибку на уровне приложения.
Проверьте IPv4 и IPv6
Иногда localhost разрешается не в:
127.0.0.1 а в IPv6:
::1 Если сервер слушает только IPv4, может возникнуть странная ситуация:
http://localhost:8000 # не работает http://127.0.0.1:8000 # работает Поэтому при непонятном поведении полезно проверить оба варианта отдельно.
Прокси и VPN могут ломать даже localhost
Особенно неприятный сценарий — приложение должно обращаться к локальному API, но системные переменные отправляют HTTP-запрос через корпоративный прокси.
Проверьте proxy-переменные PowerShell:
Get-ChildItem Env: | Where-Object { $_.Name -match "PROXY" } Часто встречаются:
HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY Для локальных сервисов обычно полезно исключить:
localhost,127.0.0.1 через NO_PROXY.
Не удаляйте корпоративные proxy-настройки вслепую. Сначала убедитесь, что именно они влияют на локальное соединение, и учитывайте политики вашей организации.
Стоит ли отключать Windows Firewall
Полностью выключать firewall ради диагностики — плохая привычка.
Сначала проверьте более вероятные причины:
- запущен ли сервер;
- правильный ли порт;
- что показывает
netstat; - на каком интерфейсе работает сервис;
- не находится ли клиент в Docker;
- доступен ли endpoint через
curl.
Firewall особенно важен, когда к AI-серверу подключаются с другого компьютера. Тогда нужно создать точечное правило для конкретного приложения или порта, а не отключать всю защиту системы.
Опасная ошибка: открыть локальную LLM на весь интернет
После борьбы с connection refused легко сделать противоположную ошибку.
Разработчик меняет:
127.0.0.1 на:
0.0.0.0 открывает порт в firewall и радуется, что всё заработало.
Но теперь API потенциально доступен другим устройствам сети, а при соответствующей настройке маршрутизатора — и извне.
Если endpoint позволяет:
- запускать дорогие модели;
- обрабатывать документы;
- вызывать инструменты;
- работать с файловой системой;
- исполнять код;
это уже полноценная поверхность атаки.
Исправление ERR_CONNECTION_REFUSED не должно превращаться в «разрешить всё всем». Открывайте только необходимые интерфейсы и порты, используйте аутентификацию и не публикуйте локальные AI-инструменты напрямую в интернет без дополнительного защитного слоя.
Как диагностировать проблему за пять минут
Для локального AI API можно использовать последовательность:
1. Проверяем URL
http://127.0.0.1:11434 2. Проверяем TCP
Test-NetConnection 127.0.0.1 -Port 11434 3. Проверяем слушающий процесс
netstat -ano | findstr :11434 4. Проверяем сам API
curl http://127.0.0.1:11434/api/tags 5. Если клиент внутри Docker
Меняем:
localhost на адрес хоста или имя Docker-сервиса в зависимости от архитектуры.
6. Только после этого проверяем код
Если ручной curl работает, а Python-приложение нет, проблема уже может находиться в:
- неправильном base URL;
- переменных окружения;
- proxy-настройках библиотеки;
- неверном endpoint;
- конфигурации SDK.
Как использовать ИИ для диагностики самого ИИ
Здесь нейросеть действительно полезна. Вместо сообщения:
У меня connection refused, что делать?
лучше сразу дать модели технический контекст.
Помоги диагностировать ERR_CONNECTION_REFUSED на Windows. Клиент работает в Docker Desktop, Ollama запущена на Windows, ожидаемый порт 11434. Не предлагай сразу отключать firewall или переустанавливать программы. Построй диагностику от нижнего уровня к верхнему: TCP-порт → слушающий процесс → bind address → Docker networking → HTTP endpoint → конфигурация клиента. Для каждого шага дай одну PowerShell-команду и объясни, как интерпретировать результат.
Такой запрос намного полезнее, потому что модель получает архитектуру системы и не перебирает случайные советы.
Что отправлять нейросети для разбора ошибки
Хороший диагностический пакет содержит:
- полный текст ошибки;
- URL, к которому выполняется подключение;
- порт;
- где работает клиент: Windows, Docker, WSL или другая машина;
- где работает сервер;
- вывод
Test-NetConnection; - вывод
netstat; - результат
curl; - небольшой фрагмент конфигурации.
Но перед отправкой удалите:
- API-ключи;
- пароли;
- access tokens;
- cookie;
- приватные домены, если они чувствительны;
- персональные данные пользователей.
Частые сценарии ERR_CONNECTION_REFUSED в AI-проектах
| Ситуация | Вероятная причина | Что проверить |
|---|---|---|
| Ollama не отвечает | Сервис не запущен или другой порт | localhost:11434, процесс Ollama |
| Docker не видит Ollama на Windows | localhost указывает внутрь контейнера | host.docker.internal |
| LM Studio не отвечает | API Server не запущен | Режим сервера и фактический порт |
| FastAPI виден на хосте, но не из контейнера | Bind только на 127.0.0.1 | Запуск с --host 0.0.0.0 |
| Контейнер недоступен с Windows | Порт не опубликован | ports: или -p |
| MCP не подключается | Неверный транспорт или сервер завершился | stdio / HTTP / URL / логи процесса |
| localhost ведёт себя странно | IPv4 / IPv6 | 127.0.0.1 и ::1 |
| Работает curl, но не Python | Proxy или неверный base URL | ENV-переменные и конфигурацию SDK |
Частые вопросы
Что означает ERR_CONNECTION_REFUSED?
Клиент не смог установить соединение с указанным адресом и портом. Обычно сервис не запущен, слушает другой порт или интерфейс либо подключение отклоняется сетевой конфигурацией.
Почему localhost работает в браузере, но не работает в Docker?
Потому что внутри контейнера localhost означает сам контейнер. Для обращения к Windows-хосту в Docker Desktop часто используется host.docker.internal, а между контейнерами Docker Compose — имя соответствующего сервиса.
Как проверить, открыт ли порт на Windows?
Самый простой вариант:
Test-NetConnection localhost -Port 11434 Значение TcpTestSucceeded: True означает, что TCP-соединение устанавливается.
Почему Ollama выдаёт connection refused?
Чаще всего нужно проверить, запущен ли сервис Ollama, действительно ли используется порт 11434 и откуда выполняется подключение. Если клиент находится в Docker, localhost:11434 обычно указывает не на Windows-хост.
Почему LM Studio показывает модель, но API не работает?
Загруженная модель и запущенный API-сервер — разные вещи. Проверьте запуск локального сервера, порт и доступность endpoint /v1/models.
Нужно ли менять DNS при ERR_CONNECTION_REFUSED на localhost?
Обычно нет. Для локальной AI-инфраструктуры сначала нужно проверить процесс, порт и сетевой интерфейс. DNS значительно актуальнее при подключении к удалённому доменному имени.
Поможет ли отключение Windows Firewall?
Иногда причиной действительно становятся сетевые правила, но полностью отключать firewall не стоит. Сначала проверьте, слушает ли приложение нужный порт, а затем при необходимости создайте точечное разрешающее правило.
Итог: сначала сеть, потом нейросеть
ERR_CONNECTION_REFUSED в AI-проекте часто заставляет разработчика искать проблему не там. Меняется модель, переустанавливается Python-пакет, переписывается клиент OpenAI API, хотя реальная причина намного проще: нужный процесс вообще не слушает указанный порт.
Правильная диагностика идёт снизу вверх:
Сервис запущен → порт слушается → TCP доступен → адрес соответствует архитектуре Docker/WSL → HTTP endpoint отвечает → только потом проверяем SDK и код AI-приложения.
Такой подход одинаково работает для Ollama, LM Studio, локальных OpenAI-совместимых API, MCP-серверов, FastAPI, RAG-систем и собственных AI-агентов.
И чем сложнее становится локальная инфраструктура искусственного интеллекта, тем полезнее помнить простую вещь: иногда самая страшная ошибка нейросети вообще не связана с нейросетью. Это просто закрытый порт.