Przejdź do treści głównej

Poradniki / Kody statusu HTTP wyjaśnione

406 Not Acceptable: co oznacza i jak naprawić

406 Not Acceptable oznacza, że serwer nie potrafi wyprodukować odpowiedzi pasującej do tego, co klient powiedział, że zaakceptuje. Samo żądanie jest w porządku; negocjacja między tym, o co poproszono, a tym, co serwer jest w stanie zaoferować, zawiodła, zwykle w kwestii formatu, języka albo kodowania odpowiedzi.

Co oznacza 406 Not Acceptable

HTTP obsługuje negocjację treści przez rodzinę nagłówków Accept: Accept dla typu medialnego odpowiedzi, Accept-Language dla języka i Accept-Encoding dla kompresji. Klient może wysłać dowolny z nich, żeby powiedzieć "daj mi tylko odpowiedź, którą mogę wykorzystać". Zgodnie z RFC 9110, jeśli serwer nie może wyprodukować reprezentacji, którą klient wskazał jako akceptowalną, i decyduje się to zasygnalizować zamiast po prostu coś wysłać, odpowiada 406. W praktyce większość serwerów po cichu ignoruje wąski nagłówek Accept i wysyła swoją domyślną odpowiedź, dlatego prawdziwe 406 jest rzadsze niż sam ten nagłówek.

Jak pojawia się błąd

Przeglądarka rzadko wywołuje 406 podczas normalnego wczytywania strony, bo przeglądarki wysyłają permisywne nagłówki Accept pasujące niemal do wszystkiego, co serwer oferuje. Znacznie częściej pojawia się to u klientów API, skryptów i narzędzi linii poleceń ustawiających restrykcyjny nagłówek Accept:

curl -i -H "Accept: application/xml" https://api.example.com/v1/status
HTTP/1.1 406 Not Acceptable
Content-Type: application/json

W tym przykładzie klient poprosił wyłącznie o XML, a API potrafi produkować tylko JSON, więc serwer odmawia zamiast wysłać format, o którym klient wprost powiedział, że go nie chce.

Co powoduje 406 Not Acceptable

  • Rzeczywista awaria negocjacji treści. Nagłówek Accept, Accept-Language albo Accept-Encoding nazywający wyłącznie formaty, których serwer nie potrafi wyprodukować, najczęściej klient żądający XML z API tylko-JSON, albo konkretny wariant językowy, którego serwer nie ma.
  • Zapora aplikacji webowej na hostingu współdzielonym. To bardzo częsta przyczyna z życia, niemająca nic wspólnego z negocjacją treści: reguły ModSecurity i podobnych WAF na środowiskach hostingu współdzielonego blokują żądania, których nagłówek Accept wygląda nietypowo, brakuje go albo wygląda automatycznie, i odpowiadają 406 jako odpowiedzią blokującą niezależnie od tego, co było negocjowane.
  • API serwujące wyłącznie JSON, trafione klientem wysyłającym Accept: text/html. Niektóre API są w tej kwestii ścisłe i odmawiają zamiast się zdegradować, co ujawnia się jako 406 dla każdego klienta, w tym karty przeglądarki otwartej bezpośrednio na endpoincie.
  • Źle skonfigurowana reguła reverse proxy albo CDN, która inspekcjonuje i odrzuca na podstawie nagłówka Accept z powodów cache'owania albo filtrowania botów, niezwiązanych z tym, co potrafi wyprodukować serwer źródłowy.
  • Zbyt restrykcyjna obsługa Accept-Encoding. Serwer skonfigurowany, żeby odrzucać każde żądanie niewymieniające preferowanej przez niego metody kompresji, zamiast wrócić do odpowiedzi nieskompresowanej.

Jak rozpoznać, kto zawinił

Jeśli tylko konkretny skrypt albo integracja trafia na 406, sprawdź, co mówią jej nagłówki Accept, bo zawężony albo źle skonfigurowany nagłówek po stronie klienta jest częstą bezpośrednią przyczyną. Jeśli to samo żądanie działa z prostym, permisywnym nagłówkiem Accept, ale zawodzi z konkretnym, serwer naprawdę nie potrafi obsłużyć tego formatu. Jeśli dotknięty jest też normalny ruch przeglądarkowy, albo błąd zaczął się zaraz po zmianie hostingu albo WAF bez zmiany kodu po Twojej stronie, bardziej prawdopodobną winą są reguły bezpieczeństwa hostingu współdzielonego, a uruchomienie kontroli HTTP z kilku lokalizacji z dokładnie tymi nagłówkami, których używa Twoja integracja, to najszybszy sposób potwierdzenia, czy blokada jest spójna, czy specyficzna dla jednej sieci.

Jak naprawić 406 Not Acceptable

Jeśli jesteś odwiedzającym

  1. Usuń albo rozluźnij nagłówek Accept w dowolnym skrypcie albo narzędziu wysyłającym żądanie, jeśli je kontrolujesz, i pozwól mu zaakceptować domyślny format oferowany przez serwer.
  2. Sprawdź dokumentację API pod kątem obsługiwanych typów treści i języków, zanim założysz, że serwer jest zepsuty.
  3. Wypróbuj żądanie bezpośrednio z przeglądarki, bo przeglądarki wysyłają szerokie nagłówki Accept i rzadko trafiają na ten błąd, co pomaga potwierdzić, że blokada jest specyficzna dla nagłówków Twojego klienta.

Jeśli prowadzisz witrynę

  1. Sprawdź najpierw reguły ModSecurity albo WAF, jeśli 406 jest niespodziewane i powszechne, bo środowiska hostingu współdzielonego często blokują na podstawie wzorców nagłówka Accept, nie prawdziwej awarii negocjacji. Spójrz na własne logi WAF pod kątem dopasowanego id reguły, zanim dotkniesz kodu aplikacji.
  2. Potwierdź, jakie formaty faktycznie serwuje Twoje API, i albo obsłuż więcej z tego, o co realnie proszą klienci, albo wyraźnie udokumentuj wymaganie, żeby 406 było informatywne, a nie zaskakujące.
  3. Wróć do domyślnej reprezentacji zamiast wprost odmawiać, tam gdzie jest to akceptowalne dla Twojego API, bo większość realnych klientów lepiej znosi "oto JSON, mimo że pytałeś ogólnie" niż jednoznaczną odmowę.
  4. Sprawdź reguły reverse proxy i CDN pod kątem czegokolwiek inspekcjonującego nagłówek Accept w celach cache'owania albo zarządzania botami, bo reguła stworzona w jednym celu może produkować 406 jako efekt uboczny dla niepowiązanego ruchu.

Jak zapobiec, żeby 406 nie zwaliło integracji

406 wprowadzone przez aktualizację bezpieczeństwa dostawcy hostingu albo nową regułę WAF nie będzie wyglądać jak awaria z wnętrza Twojej własnej sieci, bo Twoje własne żądania mogą używać innych nagłówków niż dotknięta integracja. Zaplanowana kontrola HTTP, która wysyła ten sam nagłówek Accept, którego używają Twoi prawdziwi klienci, z asercją na oczekiwanym kodzie statusu, wyłapuje awarię negocjacji w chwili, gdy się zaczyna. Sprawdzanie z wielu lokalizacji pomaga też odróżnić regułę WAF obejmującą cały hosting od takiej, która obowiązuje tylko na niektórych węzłach brzegowych.

Powiązane błędy

Zobacz 403 Forbidden dla blisko powiązanego przypadku blokady przez WAF albo regułę anty-botową wprost, a nie przez negocjację treści, przegląd 4xx dla szerszej rodziny oraz 413 Payload Too Large gdzie indziej w tej partii.

Najczęściej zadawane pytania

Czy 406 to to samo co błąd CORS?

Nie. Awarie CORS zdarzają się, bo przeglądarka odmawia ujawnienia odpowiedzi cross-origin wywołującemu skryptowi; 406 to sam serwer odmawiający wyprodukowania treści odpowiedzi, bo nie może zaspokoić żądanego formatu, języka albo kodowania.

Dlaczego widzę 406 tylko z curla albo Postmana, nigdy z przeglądarki?

Przeglądarki domyślnie wysyłają szerokie, permisywne nagłówki Accept. Narzędzia takie jak curl nie wysyłają nic albo wąski nagłówek, chyba że go ustawisz jawnie, co dużo bardziej prawdopodobnie wywoła prawdziwą awarię negocjacji albo uruchomi regułę WAF wyczuloną na nietypowe nagłówki.

Czy 406 może pochodzić z ModSecurity, nawet jeśli mój nagłówek Accept jest zupełnie normalny?

Tak. Wiele zestawów reguł ModSecurity na hostingu współdzielonym flaguje żądania jako zautomatyzowane na podstawie kombinacji sygnałów, w tym dokładnej struktury i kolejności nagłówków Accept, i odpowiada 406 jako ogólną blokadą, a nie dlatego że negocjacja treści faktycznie zawiodła.

Czy moje API powinno zwracać 406, czy po prostu domyślnie dawać JSON?

Domyślne przechodzenie na rozsądny format jest przyjaźniejsze dla realnych klientów i to robi większość produkcyjnych API. Zwracanie 406 jest uzasadnione, gdy ciche serwowanie złego formatu byłoby aktywnie mylące dla wywołującego.

Jaka jest różnica między 406 a 415?

406 dotyczy tego, co klient może zaakceptować w odpowiedzi. 415 Unsupported Media Type dotyczy tego, co serwer może zaakceptować w treści żądania wysłanej przez klienta. Obejmują przeciwne kierunki tej samej idei negocjacji.

Sprawdź teraz

Uruchom darmowe sprawdzenie na swojej stronie - bez zakładania konta.

HTTP check

Monitoruj to na stałe

Otrzymasz powiadomienie w chwili awarii: HostTracker sprawdza z ponad 300 lokalizacji i powiadamia e-mailem, SMS-em, przez Slack, Telegram i nie tylko.

Funkcje HostTracker

Więcej w tej sekcji: Kody statusu HTTP wyjaśnione