Если ваш сайт на виртуальном хостинге внезапно стал отвечать 500 Internal Server Error, это не приговор. В 9 случаях из 10 причина лежит на поверхности: синтаксическая ошибка в .htaccess, неподдерживаемая директива, неверные права на файлы и папки, ошибка PHP или неправильно выставленные лимиты в php.ini (например, слишком маленький memory_limit). Ниже — системный разбор типичных сценариев и чек-лист, который экономит часы. Если вы только выбираете тарифы, обратите внимание на наш виртуальный хостинг: доступ к логам и гибкие PHP-настройки ускоряют диагностику.
Где искать точную причину: логи и быстрые проверки
Код 500 — это «зонтик» для ошибок на стороне сервера. Чтобы понять, что именно сломалось, сразу идите в логи. На виртуальном хостинге обычно доступны:
- error_log веб-сервера — общий или выделенный под сайт. В нём видны ошибки
.htaccess,mod_rewrite, обращения к несуществующим директивам, нарушения политики suEXEC/FCGI и ошибки PHP, вылетевшие до передачи ответа. - error_log PHP — если включена запись логов PHP через
log_errors = Onи указан путь вerror_log(локальный файл в корне сайта или подкаталоге). Это помогает ловить фатальные ошибки, превышения лимитов, ошибки парсера и предупреждения.
Если логов нет, включите их принудительно. На виртуальном хостинге с PHP-FPM чаще всего сработает .user.ini в корне сайта:
log_errors = On
error_reporting = E_ALL
error_log = error.log
Для запуска проверки достаточно дернуть проблемную страницу, затем открыть error.log рядом с index.php. Важно: не включайте display_errors на боевом сайте — отдача ошибок в браузер раскрывает чувствительную информацию. Лучше работать через логи.
Никогда не правьте «наугад». Код 500 скрывает конкретику: точная причина почти всегда лежит в error_log.
.htaccess: зона повышенного риска
Файл .htaccess выполняется на каждом запросе. Любая ошибка или директива, запрещенная в контексте каталогов, приведёт к 500. Критичные сценарии:
1) Неподдерживаемые директивы PHP в .htaccess под PHP-FPM
На многих площадках PHP работает через PHP-FPM. В этом режиме директивы вида php_flag и php_value в .htaccess не поддерживаются и вызывают 500. Типичная запись, ломающая сайт:
php_flag display_errors Off
php_value memory_limit 256M
Решение: перенести настройки в php.ini или .user.ini в корень сайта:
display_errors = Off
memory_limit = 256M
Если панель хостинга поддерживает выбор версии PHP и пользовательские опции, выставьте нужные параметры там. Подробно о переносе директив в пользовательские файлы я писал в разборе: как заменить php_value на .user.ini и какие лимиты реально работают.
2) Ошибки синтаксиса и модуль mod_rewrite
Часто ломаются правила mod_rewrite: опечатки, лишние флаги, неверный порядок условий. Признаки в логе: «RewriteRule: bad flag delimiters», «maximum number of internal redirects reached» (бесконечная петля).
Базовый безопасный шаблон фронт-контроллера:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
Частые ошибки:
- Отсутствует проверка
!-fи!-d— в результате правила переписывают запросы к статике и директориям, создавая петлю. - Неправильные относительные пути в
RewriteRuleпри расположении сайта в подпапке без корректногоRewriteBase. - Комбинация канонических редиректов (HTTP→HTTPS, www→non-www) и сложных правил роутинга без условий порождает циклы.
Если у вас есть полный доступ к конфигам (например, на VDS), лучше переносить правила из .htaccess в виртуальный хост — это быстрее и безопаснее. Разбор: почему лучше убирать логику из .htaccess в конфигурацию виртуального хоста.
3) Старый синтаксис доступа под Apache 2.4
Если ваш .htaccess унаследован с эпохи Apache 2.2, директивы Order allow,deny, Deny from all, Allow from могут выбивать 500. В Apache 2.4 используется новая модель на базе Require. Например, вместо:
Order deny,allow
Deny from all
нужно:
Require all denied
Проверьте логи: там будет сообщение о неизвестной или запрещённой директиве в текущем контексте.
4) ErrorDocument и относительные пути
Некорректно заданный ErrorDocument может запустить рекурсию. Например, если 404 указывает на путь, который сам переписывается правилами и снова ведёт на 404. Надёжнее указывать абсолютный путь внутри сайта:
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html
И исключить эти файлы из переписывания через RewriteCond.

Права и владельцы: 644/755 — не просто мантра
На виртуальном хостинге под suEXEC/FCGI и схожих режимах безопасности чрезмерно открытые права (например, 777) или неверный владелец — частая причина 500. Принципы:
- Файлы: 644
- Директории: 755
- Скрипты не должны быть исполняемыми, если это не требуется (для PHP скриптов достаточно 644)
- Владелец — ваш пользователь хостинга; группа и другие не должны иметь права записи, если политика не предусматривает обратного
В логах сервер может писать «permission denied», «suexec policy violation», «Primary script unknown». Последнее часто встречается при неверных путях в конфигурации или когда файл недоступен процессу PHP-FPM из-за прав.
Не используйте 777 «на всякий случай». На хостинге с suEXEC это почти гарантированный 500 error.
PHP: фаталы, лимиты и «невидимые» ошибки
Даже если .htaccess идеален, 500 может рождаться из PHP. Типовые триггеры:
- Фатальная ошибка: вызов несуществующей функции, класс не найден, синтаксическая ошибка в новом релизе.
- Превышение
memory_limitпри обработке больших данных или активной сериализации. - Истекло время выполнения:
max_execution_timeили ограничение процессора со стороны хостинга. - Недоступные расширения: код ждёт
intl,mbstring,pdo_mysql, а в выбранной версии PHP они отключены.
Минимальный набор настроек в php.ini или .user.ini для диагностики:
log_errors = On
error_reporting = E_ALL
error_log = error.log
memory_limit = 256M
max_execution_time = 30
Если ошибка воспроизводится только на больших загрузках или импортах, временно повысьте memory_limit и max_execution_time, а также проверьте post_max_size и upload_max_filesize. Для составных форм часто забывают, что post_max_size должно быть не ниже upload_max_filesize.
PHP-FPM и .user.ini
На виртуальном хостинге PHP чаще крутится через php-fpm. Это даёт производительность, но меняет правила игры:
php_value/php_flagв.htaccessбольше не работают.- Изменения через
.user.iniподхватываются периодически (по интервалуuser_ini.cache_ttl). Дайте системе пару минут или переключите версию PHP в панели, чтобы форсировать перечитывание. - Локальные
php_admin_valueна уровне пула могут перекрывать ваши значения; если настройка не применяется — смотрите инфопоиск через тестовую страницу с phpinfo().
Если вам нужен полный контроль над пулами PHP-FPM, их лимитами и конфигом веб-сервера, рассмотрите переход на облачный VDS.
mod_rewrite: безопасные шаблоны и ловушки
Рассмотрим две практики, которые чаще всего вызывают 500 error, и как их обезвредить.
Петля из-за «канонизации + роутинг»
Типовой набор правил: редирект на HTTPS, затем редирект с www на apex (или наоборот), затем роутинг на index.php. Ошибка — редиректы стоят после роутинга или условия не исключают уже «канонизированные» запросы.
Советы:
- Сначала редиректы (HTTPS и www), потом — роутинг.
- Проверяйте заголовок Host и схему в условиях, чтобы не зациклиться.
- Исключайте реальные файлы и папки до RewriteRule приложения.
Регулярные выражения
Слишком жадные паттерны ведут к неожиданным переписываниям. Отдавайте предпочтение простым условиям и явным исключениям. В логах ищите упоминание «maximum number of internal redirects reached» — это явная петля.
Загрузка больших файлов: 500 из-за лимитов и временных директорий
При загрузке больших файлов код 500 может появляться не из-за mod_php или mod_rewrite, а по двум менее очевидным причинам:
- Лимиты PHP: проверьте
upload_max_filesize,post_max_size,max_execution_time,max_input_time. Если файл загружается долго — сервер может прервать выполнение. - Временные директории: PHP использует системный или пользовательский
upload_tmp_dir. Если каталог недоступен процессу или не хватает места, появится 500. Задайте свой путь и убедитесь, что директория существует и права корректны (обычно 755).
upload_tmp_dir = /home/USER/tmp
Не забудьте создать каталог и выставить владельца/права.

Кодировка и BOM в .htaccess
.htaccess — текст без BOM. Файл, сохранённый в UTF-8 с BOM, иногда вызывает странные ошибки парсера, особенно если директива стоит первой строкой. Пересохраните файл как «UTF-8 (без BOM)» и используйте Unix-переносы строк. Это мелочь, но она ломала проекты.
CMS-специфика: когда «виновата» платформа
Часто 500 появляется после обновления CMS/плагина. Что проверить:
- Требования по версии PHP: новая сборка ожидает, например, PHP 8.1, а у вас 7.4.
- Совместимость расширений:
intl,gd,imagick,mbstring,curl. Без них код падает на старте. - Кэш и автозагрузчик: после деплоя почистите кэш, пересоберите автозагрузку Composer.
Если ошибка воспроизводится только при определённом URI, включите детальный лог для этого маршрута и сравните окружение (Cookie, заголовки, размер POST).
Чек-лист восстановления после 500 Internal Server Error
- Откройте error_log веб-сервера и error_log PHP. Если их нет — включите
log_errorsв.user.ini. - Переименуйте
.htaccessво временный файл и проверьте сайт. Если 500 пропал — причина в правилах. - Верните
.htaccessпо частям: сначала редиректы, затем роутинг. После каждого шага проверяйте. - Убедитесь, что не используете
php_flag/php_valueв.htaccessпод PHP-FPM. Перенесите опции в.user.iniилиphp.ini. - Проверьте права и владельца: файлы 644, директории 755. Исключите 777.
- Повысьте временно
memory_limitиmax_execution_time, если в логе видны признаки нехватки памяти или таймаута. - Проверьте совместимость версий PHP и модулей расширений, особенно после обновлений CMS.
- Проверьте
ErrorDocumentи исключите рекурсию. Убедитесь, что файлы ошибок существуют и не переписываются. - Для больших загрузок проверьте
upload_max_filesize,post_max_size,max_input_time,upload_tmp_dirи свободное место. - Если ошибка «мигает» под нагрузкой, посмотрите процессы и лимиты пула PHP-FPM (доступ к статистике, slowlog), а также ограничения на стороне панели.
Примеры безопасных настроек
Минимальный .htaccess для фронт-контроллера
# Включаем mod_rewrite
RewriteEngine On
# Канонизация (пример): сначала HTTPS, потом домен
# Пример условных правил опущен для краткости — добавляйте аккуратно
# Не трогаем реальные файлы и папки
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Отдаём всё index.php
RewriteRule ^ index.php [L]
Локальный php.ini/.user.ini
display_errors = Off
log_errors = On
error_reporting = E_ALL
error_log = error.log
memory_limit = 256M
max_execution_time = 30
post_max_size = 32M
upload_max_filesize = 32M
Диагностика «по логу»: как читать подсказки
Чтение лога — навык. Вот типовые записи и что они значат:
- Invalid command 'php_flag' — директива запрещена (обычно PHP-FPM). Уберите из
.htaccess, перенесите в.user.ini. - RewriteRule: bad flag delimiters — синтаксис флагов неверен: проверьте квадратные скобки и разделители.
- Request exceeded the limit of internal redirects — петля переписей. Пересобирайте правила, добавляйте исключения.
- Permission denied — права/владелец. Проверьте 644/755 и suEXEC политику.
- PHP Fatal error: Allowed memory size of ... exhausted — не хватает памяти, увеличьте
memory_limitили оптимизируйте код. - Primary script unknown — неверный путь до скрипта или недоступен из-за прав.
Про «включить дебаг в браузер» и почему это плохая идея
Показывать ошибки пользователям небезопасно: стек-трейсы, пути в файловой системе и конфигурация окружения — подарок для злоумышленников. Используйте error_log. Если очень нужно увидеть быстрый вывод на экране, ограничьте доступ по IP и уберите настройку сразу после диагностики.
Когда проблема не в вашем коде
Иногда 500 приходит из-за внешних факторов:
- Общее обновление Apache/PHP на площадке: сломалась обратная совместимость, старые директивы не работают.
- Ограничение на уровне пула PHP-FPM (число процессов, лимиты памяти на процесс), исчерпанные inode или квота диска.
- Защитные модули (WAF, фильтры) блокируют запросы с особыми заголовками или телом.
Соберите минимальный пакет: точное время, URL, IP клиента (если есть), несколько строк из error_log и шаги воспроизведения. С этим набором поддержка разберётся быстрее.
Профилактика: чтобы 500 не повторялся
- Храните
.htaccessв Git и внедрите проверку на тестовом стенде перед выкладкой. - Используйте чек-лист для редиректов и роутинга, не смешивайте всё в один блок без условий.
- Следите за совместимостью версий PHP и расширений, заведите регламент обновлений CMS/плагинов.
- Держите правки PHP-настроек в
.user.iniили в панели, а не в.htaccess. - Мониторьте размер ошибок: алерты на новые записи в
error_logспасают часы простоя.
Итоги
500 Internal Server Error звучит пугающе, но распадается на набор типичных причин: .htaccess с нежизнеспособными директивами или петлями переписывания, некорректные права (вместо 644/755), ошибки PHP и ограничения в php.ini — memory_limit, таймауты, размер POST. Начинайте с логов (error_log), изолируйте .htaccess, переносите PHP-настройки в .user.ini, проверяйте права и совместимость версий. Такой подход даёт быстрый и предсказуемый путь к восстановлению даже на самом обычном виртуальном хостинге.


