ERR_CONNECTION_REFUSED to komunikat przeglądarki o odrzuconej próbie połączenia - serwer nie odpowiedział jeszcze żadnym kodem HTTP. Zanim cokolwiek zrestartujesz, potwierdź adres z DNS, odtwórz błąd curlem z tej samej sieci co przeglądarka i porównaj cel z nasłuchem na serwerze. Nie myl odmowy z NXDOMAIN, timeoutem ani 502.

Ta procedura zakłada, że masz dostęp do serwera, na którym usługa powinna działać. Jeśli błąd pokazuje ci cudza witryna, przejdź od razu do sekcji o tym, co możesz zrobić bez tego dostępu - zbierzesz dane, które komuś z dostępem oszczędzą zgadywania.

Co oznacza ERR_CONNECTION_REFUSED?

ERR_CONNECTION_REFUSED to sygnał, że próba połączenia została aktywnie odrzucona, zanim powstała jakakolwiek odpowiedź HTTP. Tak definiuje ten błąd Chromium w pliku net/base/net_error_list.h. W Linuksie odpowiada mu ECONNREFUSED z connect(2): pod zdalnym adresem i portem nie czekał żaden proces. Na poziomie TCP host odsyła wtedy segment RST w odpowiedzi na SYN skierowany do zamkniętego portu (RFC 9293).

Z tej definicji wynika cała dalsza diagnoza. Pakiety dotarły do jakiejś maszyny i ta maszyna odpowiedziała odmową - nie wiesz jeszcze tylko, czy to była właściwa maszyna, właściwy port i właściwa trasa. Każde z tych trzech pytań rozstrzyga osobny test, więc nie przypisuj winy aplikacji, zaporze ani routerowi, dopóki któryś test na nią nie wskaże. Odmowa jest przy tym dowodem, że trasa dowozi pakiety - dlatego pomiar osiągalności przez ping nie rozstrzygnie tego przypadku i nie zaczynaj od niego.

Po przenosinach sklepu na nowy serwer administrator otwiera stronę i widzi ERR_CONNECTION_REFUSED. Pierwszy odruch - restart nginxa - nie zmienia nic, bo nginx na nowej maszynie działa bez zarzutu. Problem siedzi gdzie indziej: DNS wciąż wskazuje stary adres, a tam usługę już wyłączono. Przeglądarka posłusznie pukała do drzwi, za którymi nikogo nie ma. Trzy sprawdzenia z tego tekstu wskazałyby to, zanim ktokolwiek dotknąłby konfiguracji.

Najpierw sprawdź, czy nazwa daje adres

Na tym samym komputerze, na którym wystąpił błąd, uruchom:

getent ahosts HOST_DO_TESTU

Podstaw pod HOST_DO_TESTU nazwę hosta z paska adresu. Baza ahosts pyta przez getaddrinfo(), czyli tą samą drogą co programy na tej maszynie, i zwraca adresy niezależnie od rodziny - dostaniesz i IPv4, i IPv6, bywa że kilka naraz. Zapisz każdy adres razem z jego rodziną, bo każdy z nich przetestujesz osobno.

Brak adresu kończy tę ścieżkę: DNS zwrócił NXDOMAIN, czyli pytana nazwa nie istnieje (RFC 1035, RFC 8020). To już nie jest problem portu ani nasłuchu - diagnozę tego przypadku opisujemy w osobnym tekście o DNS_PROBE_FINISHED_NXDOMAIN. Nie zmieniaj przy tej okazji resolvera ani nie wpisuj publicznego DNS na ślepo; bez dowodu dotyczącego badanej nazwy to tylko mieszanie w środowisku.

Zwrócony adres niczego jeszcze nie przesądza. Wiesz, dokąd klient puka - nie wiesz, czy ktoś tam nasłuchuje.

Odtwórz odmowę poza przeglądarką

Przeglądarka dokłada własny cache i własne reguły, więc odtwórz błąd narzędziem, którego wynik da się zacytować. Z tej samej sieci co przeglądarka wykonaj:

curl -sv --resolve 'HOST_DO_TESTU:PORT_USLUGI:ADRES_CURL_DO_TESTU' \
  'SCHEMAT://HOST_DO_TESTU:PORT_USLUGI/SCIEZKA_TESTOWA'

Podstaw pod SCHEMAT protokół usługi, pod PORT_USLUGI docelowy port, a pod SCIEZKA_TESTOWA ścieżkę żądania, które kończyło się błędem. ADRES_CURL_DO_TESTU to jeden z adresów zwróconych przez getent - adres IPv6 zapisz w nawiasach kwadratowych. Opcja --resolve przypina parę host - port do wskazanego adresu, dzięki czemu testujesz dokładnie ten adres, a nie ten, który curl sam by wylosował z DNS. Powtórz komendę dla każdego adresu i zapisuj kod wyjścia razem z komunikatem. Jeśli żądanie zawiera sekrety, nie wklejaj ich potem do zgłoszenia.

Kody wyjścia curl czyta się tak: 6 znaczy, że host się nie rozwiązał, 7 - że próba connect() się nie powiodła, a 28 - że operacja przekroczyła limit czasu. Kod 7 z komunikatem o odmowie potwierdza odmowę dla tego konkretnego adresu, portu i miejsca testu - i na tym jego wymowa się kończy.

Wynik testu wskazuje następną warstwę

Wynik testu Co już wiesz Co robisz dalej
getent nie zwraca adresu albo curl kończy się kodem 6 nazwa nie rozwiązuje się u badanego klienta zostaw porty w spokoju; przejdź do tekstu o DNS_PROBE_FINISHED_NXDOMAIN
kod 7 z komunikatem o odmowie pakiety doszły, ale nikt nie nasłuchiwał na tym adresie i porcie na serwerze porównaj cel klienta z wynikiem ss -ltnp
kod 28 to timeout, nie odmowa - pakiety giną zamiast wracać z RST badaj tę samą trasę jako osobny przypadek, bez mieszania go z odmową
dowolna odpowiedź HTTP połączenie się zestawia; problem leży wyżej czytaj kod odpowiedzi zamiast wracać do warstwy połączenia
odpowiedź HTTP 502 proxy odpowiada, ale samo nie dogadało się z serwerem nadrzędnym to osobny temat - diagnozę 502 opisujemy w innym tekście
lokalnie na serwerze działa, z klienta odmowa między dwoma miejscami testu coś ucina ruch badaj granicę między nimi, zanim oskarżysz aplikację

Każdy wiersz mówi tylko o badanym adresie, porcie, trasie i żądaniu. Tabela nie jest listą przyczyn - jest mapą następnego kroku.

Sprawdź nasłuch na hoście usługi

Zaloguj się na serwer, na którym usługa powinna działać, i uruchom:

ss -ltnp

ss pokazuje gniazda: -l ogranicza wynik do nasłuchujących, -t do TCP, -n zostawia numery zamiast nazw, a -p dopisuje procesy trzymające gniazda. Porównaj adres i port z listy z celem, do którego łączył się klient - w obrębie tej samej rodziny, bo nasłuch na IPv4 nie obsłuży połączenia przychodzącego po IPv6.

Ta sama odmowa na porcie usługi zdalnego dostępu ma własną ścieżkę diagnozy w procedurze połączenia SSH. Tu wychodzi klasyczne rozjechanie: usługa nasłuchuje na 127.0.0.1, a klient przychodzi z zewnątrz. Taki nasłuch przyjmuje wyłącznie połączenia z tej samej maszyny, więc lokalny test przejdzie, a zdalny skończy się odmową. Pamiętaj też o granicach tego polecenia - wpis potwierdza nasłuch w miejscu wykonania komendy, a brak nazwy procesu w wyniku nie dowodzi, że proces nie istnieje.

Sprawdź stan procesu i jego dziennik

Kiedy na liście nasłuchu brakuje oczekiwanego wpisu, zapytaj systemd o proces:

systemctl status NAZWA_USLUGI

Podstaw pod NAZWA_USLUGI jednostkę odpowiadającą za badany proces. Zobaczysz jej stan i ostatnie wpisy dziennika. Potem cofnij się w dzienniku do momentu sprzed błędu:

journalctl -u NAZWA_USLUGI --since "MOMENT_PRZED_BLEDEM"

MOMENT_PRZED_BLEDEM dobierz do zanotowanego czasu zdarzenia i strefy serwera. Opcja -u filtruje wpisy jednostki, --since ucina wszystko starsze niż wskazany moment.

Szukasz wpisu, który odpowiada odtworzonej próbie: paniki procesu, odmowy bindowania, restartu. Bez takiego wpisu nie przypisuj odmowy do awarii procesu ani do uprawnień - dopisywanie przyczyny bez śladu w dzienniku to zgadywanie z lepszym słownictwem.

Gdy usługa nasłuchuje, sprawdź adres i ścieżkę sieciową

Nasłuch jest, a klient dalej dostaje odmowę? Sprawdź, czy oba testy patrzą na ten sam świat. Przestrzenie nazw sieci izolują urządzenia, stosy IPv4 i IPv6, routing, reguły zapory i gniazda - proces w kontenerze nasłuchuje we własnym zestawie gniazd, więc ss uruchomione na hoście patrzy na inny zestaw niż ss w kontenerze.

Powtórz to samo żądanie curlem najpierw lokalnie na serwerze, potem z pierwotnego klienta. Zachowaj schemat, host, przypięty adres, rodzinę, port i ścieżkę - zmiana któregokolwiek elementu unieważnia porównanie. Różnica wyników zawęża problem do granicy między miejscami testu. Nie mówi jeszcze, która reguła zapory, NAT, WAF czy filtr u dostawcy za to odpowiada - konfiguracja tych warstw to materiał na osobne teksty. Nie wyłączaj zapory jako pierwszego testu; najpierw ustal, po której stronie granicy ginie ruch.

Czym odmowa różni się od timeoutu i od 502?

Te trzy wyniki opisują trzy różne etapy, choć dla użytkownika wyglądają podobnie: strona się nie otwiera.

NXDOMAIN zatrzymuje wszystko najwcześniej - DNS nie dał adresu, więc żadna próba połączenia się nie odbyła. Odmowa (ECONNREFUSED) i timeout (ETIMEDOUT) to dwa rozdzielne wyniki tej samej próby: odmowa jest aktywną odpowiedzią RST, timeout jest ciszą po pakietach, które nie wróciły. connect(2) wymienia je osobno i curl też - kod 7 kontra kod 28. Nie klasyfikuj ich po tym, jak długo kręcił się spinner.

HTTP 502 leży już za warstwą połączenia: klient dostał odpowiedź od proxy, które zgłasza nieprawidłową odpowiedź od swojego serwera nadrzędnego (RFC 9110). Z chwilą, gdy widzisz jakikolwiek kod HTTP, diagnoza samej odmowy połączenia jest zakończona.

Jak sprawdzić, że naprawa działa?

Napraw i zweryfikuj w tej samej kolejności, w której diagnozowałeś:

  1. Potwierdź przez ss -ltnp, że nasłuch jest na oczekiwanym adresie, porcie i w oczekiwanej rodzinie.
  2. Powtórz żądanie curlem lokalnie na serwerze - ten sam schemat, host, przypięty adres, port i ścieżka.
  3. Powtórz identyczny test z pierwotnego klienta, osobno dla każdego adresu z DNS.

Oczekiwana odpowiedź potwierdza naprawę dla badanego adresu, trasy i żądania - i tylko dla nich. Nie ogłaszaj na tej podstawie, że usługa działa z każdej sieci i pod każdym adresem spoza przetestowanej listy.

Co możesz zrobić bez dostępu do serwera?

Zbierz dane, których osoba z dostępem nie zdobędzie za ciebie: dokładny komunikat, adres bez sekretów, czas zdarzenia ze strefą oraz listę urządzeń i sieci, na których objaw występuje albo nie występuje. Z takim zgłoszeniem administrator odtworzy próbę i porówna ją z nasłuchem oraz dziennikiem zamiast zgadywać.

Czyszczenie cache, zmiana DNS, wyłączenie VPN i restart routera zmieniają twoje otoczenie, nie serwer. Któraś z tych zmian bywa obejściem, ale żadna nie jest potwierdzoną naprawą odmowy po stronie usługi - bez testów z obu stron nie wiadomo nawet, na której granicy błąd powstał.

Pytania o ERR_CONNECTION_REFUSED

Co oznacza ERR_CONNECTION_REFUSED?

To komunikat Chromium o odrzuconej próbie połączenia: pakiety dotarły do celu, ale żaden proces nie czekał na wskazanym adresie i porcie. Odpowiedź HTTP jeszcze nie powstała. Diagnoza sprowadza się do trzech pytań - czy nazwa daje adres, czy cel klienta się zgadza i czy usługa nasłuchuje.

Dlaczego serwer odrzuca połączenie?

Sam komunikat nie wskazuje jednej przyczyny. Porównaj adres i port, do których łączy się klient, z nasłuchem widocznym w ss -ltnp na serwerze, potem zajrzyj do stanu i dziennika usługi. Wniosek ogranicz do miejsca, w którym wyniki testów zaczynają się rozjeżdżać - tam siedzi błąd.

Jak sprawdzić, czy port usługi nasłuchuje?

Uruchom ss -ltnp na serwerze albo w przestrzeni sieciowej usługi. Dostaniesz nasłuchujące gniazda TCP z numerami portów i procesami, które je trzymają. Porównaj adres, rodzinę i port z celem klienta. Wpis potwierdza nasłuch w miejscu wykonania komendy, a nie dostępność usługi z każdej sieci.

Czym różni się ERR_CONNECTION_REFUSED od DNS_PROBE_FINISHED_NXDOMAIN?

NXDOMAIN znaczy, że pytana nazwa domenowa nie istnieje - klient nie dostał adresu, więc nie miał do czego pukać. ERR_CONNECTION_REFUSED pojawia się o krok dalej: adres jest, ale próba połączenia z nim została odrzucona. Które z dwojga masz przed sobą, rozstrzyga wynik getent ahosts dla badanej nazwy.

Czym różni się connection refused od connection timed out?

Odmowa przychodzi jako aktywna odpowiedź - host odsyła RST i klient od razu wie, że nikt nie nasłuchuje. Timeout to cisza po pakietach, które nie wróciły. connect(2) rozdziela ECONNREFUSED od ETIMEDOUT, a curl kod 7 od kodu 28. Nie klasyfikuj wyniku po tym, jak długo czekałeś.

Czy 502 Bad Gateway to to samo co ERR_CONNECTION_REFUSED?

Nie. Kod 502 jest już odpowiedzią HTTP: proxy odebrało żądanie i zgłasza, że samo dostało nieprawidłową odpowiedź od serwera nadrzędnego. ERR_CONNECTION_REFUSED oznacza, że żadna odpowiedź HTTP nie powstała. Widząc 502, diagnozujesz proxy i jego zaplecze, nie warstwę zestawiania połączenia.

Co może zrobić użytkownik bez dostępu do serwera?

Zapisać dokładny komunikat, adres bez sekretów, czas ze strefą oraz to, na których urządzeniach i sieciach objaw występuje. Te dane pozwalają administratorowi odtworzyć próbę i porównać ją z nasłuchem oraz dziennikiem. Czyszczenie cache i restart routera nie naprawią usługi, która po prostu nie nasłuchuje.

Dalsza diagnostyka

Pozostałe przypadki zbiera diagnostyka odmowy połączenia z usługą.

Ten tekst kończy się tam, gdzie połączenie zostaje zestawione. Brak nazwy w DNS opisujemy osobno w tekście o DNS_PROBE_FINISHED_NXDOMAIN, odpowiedź HTTP 502 - w tekście o 502 Bad Gateway, a konfigurację reverse proxy - w poradniku o reverse proxy.

Źródła

  • Chromium, net/base/net_error_list.h - definicja CONNECTION_REFUSED
  • Linux man-pages connect(2), getent(1), ss(8) i network_namespaces(7)
  • RFC 9293, sekcja 3.5.2 - segment RST dla połączenia w stanie CLOSED
  • RFC 1035, sekcja 4.1.1 i RFC 8020, sekcja 1 - znaczenie NXDOMAIN
  • RFC 9110, sekcja 15.6.3 - znaczenie HTTP 502
  • dokumentacja curl dla --resolve i libcurl-errors
  • dokumentacja systemd dla systemctl(1) i journalctl(1)