WordPress "HTTP error" при завантаженні зображення: дерево рішень, яке справді знаходить причину
Знайдіть справжню причину помилки HTTP error при завантаженні зображення у WordPress однією перевіркою, а потім лагодьте потрібну гілку: фаєрвол, пам'ять PHP, post_max_size чи Imagick.
Опубліковано
«HTTP error» — це не причина. Це визнання завантажувача медіафайлів у тому, що він надіслав ваш файл на сервер і отримав відповідь, яку не зміг розібрати як успішну, — а такі самі два слова дають щонайменше шість не пов’язаних між собою збоїв. Вгадування між ними і є причиною того, що люди витрачають півдня на підняття upload_max_filesize на сайті, справжня проблема якого — правило фаєрвола.
Найшвидший вихід — одне спостереження, яке ділить шість причин на дві групи, а далі одна перевірка на кожну гілку.
Спершу: прочитайте справжню відповідь
Відкрийте інструменти розробника у браузері, перейдіть на вкладку «Мережа» і завантажте файл ще раз. Слідкуйте за запитом до async-upload.php. Те, що повернеться, і є вашим діагнозом.
| Що ви бачите | Що це означає | Куди далі |
|---|---|---|
| 403 або 406, тіло у вигляді HTML | Запит відхилив фаєрвол або mod_security | Гілка A |
| 500, порожня відповідь або обрізане тіло | PHP аварійно завершився або вичерпав пам’ять посеред обробки | Гілка B |
| 413 | Тіло запиту перевищило серверний ліміт | Гілка C |
| 200, але тіло не є чистим JSON | Плагін чи шаблон вивів щось перед відповіддю | Гілка D |
| Запит ніколи не завершується / вичерпано час очікування | Ліміт часу виконання, зазвичай на великих файлах | Гілка B |
Один погляд відсіює більшість порад з інтернету за вас. Якщо дістатися до інструментів браузера не виходить, спершу увімкніть журналювання у wp-config.php:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
Відтворіть завантаження, а потім прочитайте wp-content/debug.log. Рядок із фатальною помилкою прямо називає гілку. Якщо рядок надто густий, вставте його в декодер журналу помилок — він зіставляє типові сигнатури фатальних помилок із тим, що насправді зламалося.
Гілка A — фаєрвол або правило mod_security
Код 403 зі сторінкою HTML у тілі відповіді означає, що запит взагалі не дійшов до WordPress. Щось попереду — mod_security, Cloudflare, Wordfence, Sucuri або власний набір правил вашого хостингу — вирішило, що POST виглядає зловмисно.
Перевірка: тимчасово вимкніть будь-який плагін безпеки і завантажте файл знову. Якщо нічого не змінилося, правило живе на рівні сервера, і треба, щоб хостинг подивився журнал аудиту mod_security за міткою часу невдалого завантаження. Вони можуть додати конкретний ID правила у виняток.
Будьте чесні щодо порад, які ви тут знайдете. Фрагменти, що радять вкинути таке в .htaccess:
SecFilterEngine Off
SecFilterScanPOST Off
розраховані на mod_security 1.x, який практично вимер. На сучасному сервері ці директиви або нічого не роблять, або дають помилку 500 і роблять сайт ще гіршим. Сучасний mod_security використовує SecRuleEngine, і більшість керованих хостингів усе одно забороняє перевизначати його на рівні окремих тек. Питайте хостинг, а не вставляйте наосліп.
Гілка B — ліміти пам’яті або часу виконання PHP
Це найпоширеніша гілка і водночас та, що має найчіткішу ознаку: збої нестабільні. Той самий файл завантажується з третьої спроби, або фото на 2 МБ падає, а PDF на 6 МБ проходить без проблем. Жорсткі конфігураційні ліміти дають збій щоразу однаково. Проблеми з пам’яттю — ні, бо доступний обсяг залежить від того, чим ще зайнятий сервер.
Чому саме зображення: WordPress не просто зберігає файл, а розпаковує його в сирі пікселі, щоб згенерувати кожен проміжний розмір — medium_large, усе зареєстроване через add_image_size, woocommerce_thumbnail, якщо у вас магазин, плюс копію -scaled, якщо зображення більше за big_image_size_threshold. JPEG на 12 мегапікселів займає кілька МБ на диску і приблизно 48 МБ у пам’яті — і це ще до буфера для зміни розміру. Ліміт у 128 МБ зникає дуже швидко.
Підніміть його у wp-config.php, вище рядка про припинення редагування:
define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );
Реальна ціна: WP_MEMORY_LIMIT не може перевищити те, що дозволяє сам PHP. Якщо ваш хостинг обмежує memory_limit значенням 128M, ця константа суто декоративна. Перевіряйте справжнє значення в «Інструменти → Стан сайту → Інформація → Сервер», а не в тому, що ви написали. Якщо стелею є власний ліміт PHP, зрушити його може лише хостинг.
Гілка C — розмір файлу та ліміти POST-запиту
Подивіться реальні числа в «Інструменти → Стан сайту → Інформація → Обробка медіафайлів». Значення мають два параметри, а змінюють люди завжди лише один:
upload_max_filesize— обмеження на один файл.post_max_size— обмеження на усе тіло запиту.
Якщо весь POST перевищує post_max_size, PHP відкидає запит ще до того, як WordPress виконає бодай рядок коду. Повертати нічого, тож завантажувач отримує відповідь, яку неможливо розібрати, і каже «HTTP error». post_max_size завжди має бути з добрим запасом більшим за upload_max_filesize.
Застереження, яке варто знати: коли файл перевищує лише upload_max_filesize, завантажувач зазвичай ловить це ще в браузері й повідомляє, що файл перевищує максимальний розмір, — це зрозуміліше повідомлення. Тож голе «HTTP error» частіше вказує на post_max_size або на гілку B, ніж на той параметр, який усі піднімають першим.
Де саме їх змінювати — залежить від вашого стека. На Apache з mod_php працює .htaccess:
php_value upload_max_filesize 64M
php_value post_max_size 128M
На PHP-FPM, LiteSpeed чи NGINX — а це більшість сучасного хостингу — ці рядки не роблять нічого і можуть дати помилку 500. Використовуйте панель налаштувань PHP від хостингу або файл .user.ini. NGINX до того ж має власний ліміт client_max_body_size, підняти який може тільки хостинг.
Гілка D — бібліотека для роботи із зображеннями (Imagick проти GD)
WordPress віддає перевагу ImageMagick, коли розширення PHP присутнє, і відкочується до GD. На дешевих хостингах проблема часто саме в ImageMagick: його файл політики обмежує пам’ять, диск і площу зображення на одну операцію, і коли зміна розміру впирається в один з цих лімітів, процес помирає без жодного корисного повідомлення. Зазвичай це видно на великих зображеннях, тоді як малі проходять — виглядає як гілка B, але нею не є.
Примусово увімкніть GD, щоб перевірити гіпотезу:
add_filter( 'wp_image_editors', function ( $editors ) {
return array( 'WP_Image_Editor_GD' );
} );
Покладіть це у functions.php або в невеликий mu-плагін, повторіть завантаження, а потім приберіть, якщо нічого не змінилося.
Чесний компроміс: GD не є однозначно кращим. Він тримає повний нестиснений растр у пам’яті PHP, тож на дуже великих файлах може впертися в memory_limit там, де ImageMagick — який частково працює поза виділеною для PHP пам’яттю — упорався б. Перемикання може обміняти один збій на інший. Сприймайте його спершу як діагностику і лише потім як виправлення.
Гілка E — права доступу до теки завантажень
Рідкість на керованому хостингу, але звична річ одразу після міграції або ручного перенесення сервера. Якщо wp-content/uploads недоступна для запису користувачеві веб-сервера або нова підтека року/місяця успадкувала не того власника, запис не відбувається.
ls -ld wp-content/uploads
ls -ld wp-content/uploads/2026/07
Теки зазвичай мають бути 755 і належати тому користувачеві, від імені якого працює PHP. Не ставте 777 тільки тому, що так порадили на форумі: це усуває симптом ціною того, що тека стає доступною для запису кожному обліковому запису на сервері, а на спільному хостингу це справжня діра.
Гілка F — ім’я файлу
Найдешевша перевірка зі списку, тож зробіть її рано, хоч вона й найменш імовірна. Перейменуйте файл, лишивши прості малі латинські літери, цифри та дефіси — без діакритики, апострофів, амперсандів, # і нелатинських символів — і завантажте знову. Спеціальні символи час від часу зачіпають правило безпеки або ламаються на файловій системі з невідповідним кодуванням. Десять секунд, щоб виключити цей варіант.
Чого робити не варто
Не починайте з вимкнення всіх плагінів. Це руйнівно і перевіряє лише гілки A та D. Мережева відповідь скаже вам більше за п’ять секунд.
Не додавайте випадковий рядок з обробником у .htaccess. Фрагменти, що ходять по мережі і додають директиву SetHandler чи AddHandler, розраховані на конкретне налаштування PHP конкретного хостингу. На чужому стеку вони кладуть увесь сайт з помилкою 500.
Не вважайте «спрацювало з другої спроби» виправленням. Нестабільний успіх — це підпис гілки B, і збій повернеться щойно сервер буде завантажений або хтось вивантажить щось більше.
Досі не виходить?
Якщо відповідь — чистий 200 із коректним JSON, а завантаження все одно не працює, поломка стається вже після того, як файл потрапив на сервер: зазвичай це плагін, підвішений на ланцюжок обробки вкладень, що спричиняє фатальну помилку, або плагін оптимізації, який шле власний запит до зовнішнього сервісу і не дочікується відповіді. Увімкніть WP_DEBUG_LOG, відтворіть проблему і прогоніть отриману фатальну помилку через декодер журналу помилок, щоб побачити, який файл і який хук насправді відповідальні.
FAQ
Питання
Що означає HTTP error при завантаженні зображень у WordPress?
Це означає, що завантажувач у браузері надіслав файл на сервер і отримав у відповідь щось, що не вдалося розібрати як коректну успішну відповідь. Повідомлення описує симптом, а не причину. Аварійне завершення процесу PHP, блокування фаєрволом, відповідь 403 і порожня відповідь дають одні й ті самі два слова.
Чому одне й те саме зображення іноді завантажується, а іноді ні?
Нестабільні збої майже завжди вказують на вичерпання пам'яті або процесорного часу, а не на конфігураційний ліміт. Зміна розміру великого фото потребує різкого сплеску пам'яті, а на дешевому хостингу доступний обсяг залежить від навантаження сервера. Жорсткий ліміт на кшталт post_max_size натомість дає збій щоразу однаково.
Чи виправляє перемикання WordPress з Imagick на GD помилки HTTP error?
Іноді так, але лише для однієї конкретної гілки. ImageMagick на дешевих хостингах часто обмежений файлом політики або низькими лімітами ресурсів і падає там, де GD спрацьовує. Проте GD витрачає більше пам'яті на дуже великі файли, тож перемикання може навіть погіршити збої, спричинені пам'яттю.
Як зрозуміти, що завантаження блокує фаєрвол хостингу?
Відкрийте мережеву панель у браузері, завантажте файл і подивіться на код статусу відповіді для async-upload.php. Код 403 або 406 з тілом у вигляді HTML означає, що запит відхилив веб-фаєрвол або правило mod_security. Код 500 або порожня відповідь натомість вказують на аварійне завершення PHP.
Чи виправить збільшення upload_max_filesize помилку HTTP error?
Лише якщо файл справді перевищує ваші ліміти, причому post_max_size зазвичай важливіший. Якщо все тіло запиту більше за post_max_size, PHP відкидає його ще до запуску WordPress, і завантажувач не отримує нічого. Підняти одне значення без іншого — залишити збій рівно там, де він був.
Чи може ім'я файлу спричинити помилку HTTP error у WordPress?
Так, хоча це найрідкісніша гілка. Символи з діакритикою, апострофи, амперсанди та нелатинські абетки можуть зачепити правило безпеки або зламати шлях через невідповідне кодування файлової системи. Перейменування на прості малі латинські літери, цифри та дефіси нічого не коштує і закриває цю гілку секунд за десять.