Przejdź do treści
Błędy i awarie

WordPress i „błąd HTTP” przy wysyłaniu zdjęć: drzewko decyzyjne, które naprawdę znajduje przyczynę

Ustal prawdziwą przyczynę błędu HTTP przy wysyłaniu zdjęć w WordPressie jednym sprawdzeniem, a potem napraw właściwą gałąź: firewall, pamięć PHP, post_max_size albo Imagick.

Opublikowano

„Błąd HTTP” to nie przyczyna. To moduł wysyłania mediów przyznający się, że przesłał plik na serwer i dostał odpowiedź, której nie potrafił odczytać jako sukcesu — a co najmniej sześć niepowiązanych ze sobą awarii daje dokładnie te same dwa słowa. Zgadywanie między nimi to powód, dla którego ludzie tracą całe popołudnie na podnoszenie upload_max_filesize na stronie, której prawdziwym problemem jest reguła firewalla.

Najszybsze wyjście to jedna obserwacja, która dzieli te sześć przyczyn na dwie grupy, a potem jedno sprawdzenie na gałąź.

Najpierw: przeczytaj faktyczną odpowiedź

Otwórz narzędzia deweloperskie przeglądarki, przejdź na kartę Sieć i wyślij plik jeszcze raz. Wypatruj żądania do async-upload.php. To, co wraca, jest twoją diagnozą.

Co widziszCo to znaczyIdź do
403 lub 406, treść HTMLŻądanie odrzucił firewall albo mod_securityGałąź A
500, pusta odpowiedź albo ucięta treśćPHP padło lub zabrakło mu pamięci w trakcieGałąź B
413Ciało żądania przekroczyło limit serweraGałąź C
200, ale treść to nie czysty JSONWtyczka lub szablon wypisały coś przed odpowiedziąGałąź D
Żądanie się nie kończy / timeoutLimit czasu wykonania, zwykle przy dużych plikachGałąź B

To jedno spojrzenie odsiewa za ciebie większość porad krążących po internecie. Jeśli nie masz jak dostać się do narzędzi przeglądarki, włącz najpierw logowanie w wp-config.php:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

Powtórz wysyłkę, a potem przeczytaj wp-content/debug.log. Linia z błędem krytycznym wskaże gałąź wprost. Jeśli jest zbita i nieczytelna, wklej ją do dekodera dziennika błędów — mapuje typowe sygnatury błędów krytycznych na to, co faktycznie się zepsuło.

Gałąź A — firewall albo reguła mod_security

Kod 403 ze stroną HTML w treści oznacza, że żądanie nigdy nie dotarło do WordPressa. Coś przed nim — mod_security, Cloudflare, Wordfence, Sucuri albo własny zestaw reguł hostingu — uznało, że POST wygląda podejrzanie.

Sprawdzenie: tymczasowo wyłącz wtyczki bezpieczeństwa i wyślij plik ponownie. Jeśli nic to nie zmienia, reguła siedzi na poziomie serwera i potrzebujesz, żeby hosting zajrzał do dziennika audytu mod_security pod znacznikiem czasu nieudanej wysyłki. Mogą dodać konkretny identyfikator reguły do białej listy.

Bądź ze sobą szczery co do porad, które tu znajdziesz. Fragmenty każące wkleić to do .htaccess:

SecFilterEngine Off
SecFilterScanPOST Off

dotyczą mod_security 1.x, które praktycznie wymarło. Na nowoczesnym serwerze te dyrektywy albo nic nie robią, albo rzucają błąd 500, który pogarsza sprawę. Współczesne mod_security używa SecRuleEngine, a większość hostingów zarządzanych i tak blokuje nadpisywanie go per katalog. Zapytaj hosting; nie wklejaj.

Gałąź B — limity pamięci albo czasu wykonania PHP

To najczęstsza gałąź i ta z najwyraźniejszym sygnałem: występuje losowo. Ten sam plik wchodzi za trzecim razem albo zdjęcie 2 MB nie przechodzi, a PDF 6 MB owszem. Twarde limity konfiguracyjne zawodzą identycznie za każdym razem. Awarie pamięci nie, bo dostępna ilość zależy od tego, co akurat robi serwer.

Dlaczego akurat zdjęcia: WordPress nie tylko zapisuje plik, ale rozpakowuje go do surowych pikseli, żeby wygenerować każdy rozmiar pośredni — medium_large, wszystko zarejestrowane przez add_image_size, woocommerce_thumbnail, jeśli prowadzisz sklep, plus kopię -scaled, jeśli obraz przekracza big_image_size_threshold. JPEG o rozdzielczości 12 megapikseli waży kilka MB na dysku i mniej więcej 48 MB w pamięci, jeszcze przed buforem skalowania. Limit 128 MB znika błyskawicznie.

Podnieś go w wp-config.php, powyżej linii „stop editing”:

define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );

Prawdziwy haczyk: WP_MEMORY_LIMIT nie może przekroczyć tego, na co pozwala samo PHP. Jeśli hosting ustawia memory_limit na 128M, ta stała jest tylko dekoracją. Sprawdź rzeczywistą wartość w Narzędzia → Stan witryny → Informacje → Serwer, a nie w tym, co wpisałeś. Jeśli sufitem jest limit samego PHP, ruszyć go może tylko hosting.

Gałąź C — limity rozmiaru pliku i żądania

Sprawdź konkretne liczby w Narzędzia → Stan witryny → Informacje → Obsługa mediów. Liczą się dwa ustawienia, a ludzie zmieniają zawsze tylko jedno:

  • upload_max_filesize — limit dla pojedynczego pliku.
  • post_max_size — limit dla całego ciała żądania.

Jeśli cały POST przekracza post_max_size, PHP odrzuca żądanie, zanim WordPress wykona jakikolwiek kod. Nie ma czego zwrócić, więc moduł wysyłania dostaje odpowiedź, której nie umie odczytać, i mówi „błąd HTTP”. post_max_size powinien być zawsze wyraźnie większy niż upload_max_filesize.

Zastrzeżenie, które warto znać: kiedy plik przekracza wyłącznie upload_max_filesize, moduł wysyłania zwykle wyłapuje to jeszcze w przeglądarce i informuje, że plik przekracza maksymalny rozmiar wysyłki — czyli daje wyraźniejszy komunikat. Więc goły „błąd HTTP” częściej wskazuje na post_max_size albo na gałąź B niż na ustawienie, które wszyscy podnoszą jako pierwsze.

Gdzie je zmienić, zależy od twojego stosu. Na Apache z mod_php działa .htaccess:

php_value upload_max_filesize 64M
php_value post_max_size 128M

Na PHP-FPM, LiteSpeed albo NGINX — czyli na większości nowoczesnych hostingów — te linie nic nie robią, a mogą rzucić błąd 500. Użyj wtedy panelu ustawień PHP w hostingu albo pliku .user.ini. NGINX narzuca też własny client_max_body_size, który może podnieść tylko hosting.

Gałąź D — biblioteka edytora obrazów (Imagick kontra GD)

WordPress woli ImageMagick, kiedy rozszerzenie PHP jest dostępne, a w przeciwnym razie schodzi do GD. Na hostingach współdzielonych ImageMagick jest częstym sprawcą: jego plik konfiguracji polityk ogranicza pamięć, dysk i powierzchnię obrazu na operację, a gdy skalowanie przekroczy któryś z tych limitów, proces umiera bez sensownego komunikatu. Zwykle widać to przy dużych obrazach, podczas gdy małe przechodzą — co wygląda jak gałąź B, ale nią nie jest.

Wymuś GD, żeby sprawdzić tę hipotezę:

add_filter( 'wp_image_editors', function ( $editors ) {
    return array( 'WP_Image_Editor_GD' );
} );

Wrzuć to do functions.php albo małej wtyczki mu-plugin, powtórz wysyłkę, a jeśli nic się nie zmieni — usuń.

Uczciwy kompromis: GD nie jest bezwzględnie lepszy. Trzyma całą nieskompresowaną bitmapę w pamięci PHP, więc przy bardzo dużych plikach potrafi uderzyć w memory_limit tam, gdzie ImageMagick — działający częściowo poza alokacją PHP — by sobie poradził. Taka zmiana może zamienić jedną awarię na drugą. Traktuj ją najpierw jako diagnostykę, a dopiero potem jako naprawę.

Gałąź E — uprawnienia katalogu uploads

Rzadkie na hostingach zarządzanych, częste zaraz po migracji albo ręcznej przeprowadzce serwera. Jeśli wp-content/uploads nie jest zapisywalny dla użytkownika serwera WWW albo świeżo utworzony podkatalog rok/miesiąc odziedziczył złego właściciela, zapis się nie uda.

ls -ld wp-content/uploads
ls -ld wp-content/uploads/2026/07

Katalogi powinny mieć zwykle 755 i należeć do użytkownika, na którym działa PHP. Nie ustawiaj 777 tylko dlatego, że ktoś tak napisał na forum — to leczy objaw, czyniąc folder zapisywalnym dla każdego konta na serwerze, co na hostingu współdzielonym jest realnym zagrożeniem.

Gałąź F — nazwa pliku

Najtańsze sprawdzenie z całej listy, więc zrób je wcześnie, choć jest najmniej prawdopodobne. Zmień nazwę pliku na same małe litery, cyfry i myślniki — bez polskich znaków, apostrofów, ampersandów, # czy znaków niełacińskich — i wyślij ponownie. Znaki specjalne czasem uruchamiają regułę bezpieczeństwa albo psują się na systemie plików z niezgodnym kodowaniem. Dziesięć sekund, żeby to wykluczyć.

Czego nie robić

Nie zaczynaj od wyłączania wszystkich wtyczek. To uciążliwe, a testuje tylko gałąź A i gałąź D. Odpowiedź sieciowa mówi ci więcej w pięć sekund.

Nie dodawaj przypadkowej linii z handlerem do .htaccess. Krążące fragmenty dodające dyrektywę SetHandler albo AddHandler zakładają konkretną konfigurację PHP u konkretnego hostingu. Na niewłaściwym stosie kładą całą stronę błędem 500.

Nie uznawaj „za drugim razem poszło” za naprawę. Sporadyczny sukces to podpis gałęzi B i wróci w momencie, gdy serwer będzie zajęty albo ktoś wyśle coś większego.

Nadal nie działa?

Jeśli odpowiedź to czyste 200 z poprawnym JSON-em, a wysyłka i tak zawodzi, awaria następuje po zapisaniu pliku — zwykle wtyczka podpięta pod łańcuch przetwarzania załącznika rzuca błąd krytyczny albo wtyczka optymalizująca wysyła własne żądanie do zewnętrznej usługi, które się nie kończy. Włącz WP_DEBUG_LOG, powtórz wysyłkę i przepuść powstały błąd krytyczny przez dekoder dziennika błędów, żeby zobaczyć, który plik i który hook naprawdę za to odpowiada.

FAQ

Pytania

Co oznacza „błąd HTTP” przy wysyłaniu zdjęć do WordPressa?

Oznacza, że przeglądarkowy moduł wysyłania przesłał plik na serwer i dostał w odpowiedzi coś, czego nie potrafił odczytać jako poprawnego potwierdzenia. Ten komunikat opisuje objaw, a nie przyczynę. Padnięty proces PHP, blokada firewalla, kod 403 i pusta odpowiedź dają dokładnie ten sam napis.

Dlaczego to samo zdjęcie raz wysyła się dobrze, a raz nie?

Awarie występujące losowo prawie zawsze wskazują na wyczerpanie pamięci lub procesora, a nie na limit w konfiguracji. Przeskalowanie dużego zdjęcia wymaga skoku zapotrzebowania na pamięć, a na hostingu współdzielonym dostępna ilość zmienia się wraz z obciążeniem serwera. Twardy limit w rodzaju post_max_size zawodzi identycznie za każdym razem.

Czy przełączenie WordPressa z Imagick na GD naprawia błędy HTTP?

Czasem, i tylko dla jednej konkretnej gałęzi. ImageMagick na hostingach współdzielonych bywa ograniczony plikiem polityki albo niskimi limitami zasobów i zawodzi tam, gdzie GD daje radę. Z drugiej strony GD zużywa więcej pamięci przy bardzo dużych plikach, więc taka zmiana może pogorszyć awarie wynikające z pamięci.

Jak sprawdzić, czy to firewall hostingu blokuje wysyłkę?

Otwórz narzędzia sieciowe w przeglądarce, wyślij plik i zobacz, jaki kod statusu wraca dla async-upload.php. Kod 403 lub 406 z treścią HTML oznacza, że żądanie odrzucił firewall aplikacyjny albo reguła mod_security. Kod 500 lub pusta odpowiedź wskazują raczej na padające PHP.

Czy zwiększenie upload_max_filesize naprawi błąd HTTP?

Tylko jeśli plik faktycznie przekracza twoje limity, a zwykle ważniejszy jest post_max_size. Jeśli całe ciało żądania jest większe niż post_max_size, PHP odrzuca je, zanim WordPress w ogóle się uruchomi, i moduł wysyłania nie dostaje nic. Podniesienie jednego bez drugiego zostawia awarię dokładnie tam, gdzie była.

Czy nazwa pliku może wywołać błąd HTTP w WordPressie?

Tak, choć to najrzadsza gałąź. Polskie znaki, apostrofy, ampersandy i alfabety niełacińskie potrafią wywołać regułę bezpieczeństwa albo zepsuć ścieżkę przy niezgodnym kodowaniu systemu plików. Zmiana nazwy na same małe litery, cyfry i myślniki nic nie kosztuje i wyklucza tę gałąź w jakieś dziesięć sekund.