PHP: session_start(): Failed to read session data / Cannot send session cookie

  • Обновлено
  • Чтение ≈ 5 минут

Краткий ответ

Предупреждения PHP «session_start(): Cannot send session cache limiter - headers already sent» возникают, когда вывод начался до session_start. Уберите пробелы и BOM перед <?php, перенесите session_start в начало файла, используйте буферизацию вывода.

В этой статье
  1. Что происходит
  2. Причины
  3. Порядок
  4. Если ошибка идёт из чужого кода
Cannot modify header information - headers already sent
Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /var/www/index.php:1)
По-русскиЗаголовки уже отправлены.

#Что происходит

Функция session_start() отправляет заголовок cookie сессии и заголовки кэширования. HTTP-заголовки должны быть отправлены до начала тела ответа. Если любой вывод (даже один пробел или перевод строки) попал в ответ раньше, PHP не может добавить заголовки и выводит предупреждение с указанием файла и строки, где начался вывод: output started at /path/file.php:1. Это же объясняет ошибку Cannot modify header information для функций header() и setcookie(). Причины: пробелы вне тегов PHP, BOM в UTF-8 файле, echo до session_start, закрывающий тег ?> с пробелом после него, подключаемые файлы с выводом, включённый вывод ошибок до заголовков.

#Причины

Возможная причинаКак узнатьЧто делать
Пробелы перед <?phpРедактор.Вывод в строке 1.Удалите.
BOM в UTF-8 файлеБлокнот.Невидимый символ.Сохраните без BOM.
echo до session_startПорядок.Вывод выше.Перенесите вызов.
Закрывающий тег с пробеломКонец файла.Вывод в последней строке.Уберите ?>.
Подключаемый файл выводит текстinclude.Указан другой файл.Исправьте его.
Сессия стартует дваждыПовтор.Notice о сессии.session_status().

#Порядок

  1. Прочитайте текст ошибки: в скобках указан файл и строка, где начался выводЭто могут быть РАЗНЫЕ ошибки: Cannot send session cookie - headers already sent означает, что HTTP-заголовки уже отправлены, а Failed to read session data указывает, например, на проблемы хранилища сессий. Сначала в закрытом журнале PHP найдите полный текст ошибки, временную метку, имя файла и строку. Не публикуйте содержимое сессионных данных или cookies. Если есть headers already sent, выполните шаги 2–8; если ошибка чтения данных — начните сразу с проверки session.save_path и обработчика сессий.
  2. Откройте файл и уберите пробелы, пустые строки и любой текст до <?phpПри headers already sent откройте в редакторе указанный в сообщении PHP-файл и строку, где НАЧАЛСЯ вывод (после слов output started at), а не только строку session_start(). Убедитесь, что до <?php нет HTML, пробелов или echo. Переместите формирование HTTP-заголовков и запуск сессии до вывода; не удаляйте видимый HTML из шаблона без оценки последствий.
  3. Сохраните файлы в UTF-8 без BOMЕсли вывод начался в первой строке PHP-файла, проверьте его кодировку. В VS Code откройте файл → нажмите на отображаемую в нижней строке кодировку → «Сохранить с кодировкой» → «UTF-8» без BOM. В других редакторах название действия отличается. Перед изменением сохраните копию и проверьте, что русский текст и подключаемые файлы не повреждены. BOM — три невидимых байта до <?php, которые могут отправить вывод.
  4. Удалите закрывающий тег ?> в конце файлов, содержащих только PHP-кодВ файлах, содержащих только PHP-код, обычно не нужен завершающий ?>: откройте такой файл в редакторе, удалите его и пустые строки после него, сохраните и проверьте php -l путь/к/файлу. В шаблоне с HTML этот тег может быть частью разметки и удалять его не надо. Повторите запрос к странице, прежде чем менять следующие файлы.
  5. Вызывайте session_start() в самом начале скрипта, до любого вывода и доОткройте основной PHP-контроллер и найдите место вызова session_start(). Он должен выполняться после загрузки необходимых настроек и до любого HTML/echo, если сессия ещё не активна; при нескольких точках входа используйте session_status() === PHP_SESSION_NONE. Сохраните файл и проверьте, что заголовки Cookie в ответе корректны (F12 → «Сеть» → «Заголовки»); не оставляйте диагностический вывод данных сессии посетителям.
  6. Убедитесь, что до этого не выводятся echo, print, var_dumpПоиск ранее отправленного вывода: в файлах, которые подключаются до session_start(), найдите echo, print, var_dump, die() и HTML вне PHP. Временно отключите лишь конкретный отладочный вывод на тестовом окружении и перезапустите запрос. Если ошибка исчезла, перенесите этот вывод после установки заголовков или замените серверным журналированием error_log() без секретов.
  7. Включите буферизацию выводаБуферизация (ob_start() или output_buffering) может скрыть последствия раннего вывода, но НЕ исправляет ошибку чтения сессии. Используйте её только как осознанный временный приём в тестовой среде и не откладывайте устранение реального headers already sent. При внедрении убедитесь, что приложение правильно завершает и отправляет буфер, иначе возникают лишнее потребление памяти и задержки.
  8. Проверьте, что сессия не стартует дважды: используйте session_status()Проверьте, не вызывает ли приложение session_start() повторно: в редакторе выполните поиск по проекту, затем убедитесь, что перед запуском стоит if (session_status() === PHP_SESSION_NONE). При необходимости используйте уже активную сессию, не запускайте её снова. Проверьте исходные сообщения PHP; если проблема в пользовательском обработчике сессий (Redis, БД), проверять нужно его подключение, а не BOM.
  9. Проверьте права на каталог сессийПри Failed to read session data в администраторской среде откройте терминал веб-сервера и выполните php -i | grep session.save_path для CLI, затем отдельно проверьте фактическую настройку PHP-FPM используемого сайта в панели/конфигурации (она может отличаться). Администратор должен проверить существование каталога, свободное место, доступ к файлам для пользователя PHP и ошибки обработчика в журнале. Не выполняйте рекурсивный chmod 777 и не заменяйте бездумно права системной директории; исправляйте только установленную первопричину.
  10. Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
    Выберите подходящий вариант — это не команды для последовательного выполнения
    Вариант 1Правильный порядок: сессия до любого вывода
    PHPКоманда
    Правильный порядок: сессия до любого вывода
    <?php
    declare(strict_types=1);
    if (session_status() === PHP_SESSION_NONE) {
    session_start();
    }
    // далее логика и вывод
    echo 'Привет, ' . htmlspecialchars($_SESSION['user'] ?? 'гость');
    Вариант 2Диагностика: где начался вывод
    PHPКоманда
    Диагностика: где начался вывод
    <?php
    if (headers_sent($file, $line)) {
    echo "Вывод начался в $file:$line";
    }
    Вариант 3Замените file.php настоящим файлом; никаких изменений не вносит
    Linux · Терминал (Bash)Команда
    Замените file.php настоящим файлом; никаких изменений не вносит
    # Для одного известного файла на Linux/macOS: первые 3 байта до тега <?php
    xxd -l 3 file.php
    # Если вывод: ef bb bf — в начале файла есть BOM
    Вариант 4Исходное sed -i удалено во избежание порчи кодировки
    Linux · Терминал (Bash)Команда
    Исходное sed -i удалено во избежание порчи кодировки
    # Диагностика только одной резервной копии файла: сначала cp file.php file.php.bak
    # Удаляйте BOM через редактор, не применяйте sed -i ко всем файлам
    Вариант 5Удалена ошибочная конструкция find с небезопасным разбиением имён по пробелам
    Linux · Терминал (Bash)Команда
    Удалена ошибочная конструкция find с небезопасным разбиением имён по пробелам
    # Находите файлы через поиск редактора, не делайте автоматических массовых изменений
    # VS Code: Ctrl+Shift+F, строка поиска: session_start(
    Вариант 6Это диагностика, не рекомендация включать буферизацию ради ошибки чтения сессии
    INIКоманда
    Это диагностика, не рекомендация включать буферизацию ради ошибки чтения сессии
    # Без изменения конфигурации: в нужном PHP-окружении
    php -r 'print_r(["output_buffering"=>ini_get("output_buffering"),"session.save_path"=>ini_get("session.save_path")]);'
    # CLI и PHP-FPM могут иметь разные значения
    Вариант 7Команда chmod 1733 удалена как универсальный рецепт; каталог может быть иным
    Linux · Терминал (Bash)Команда
    Команда chmod 1733 удалена как универсальный рецепт; каталог может быть иным
    # Диагностика только на сервере с правами администратора
    ls -ld /var/lib/php/sessions
    # Сверьте владельца и права с действительной конфигурацией PHP-FPM

#Если ошибка идёт из чужого кода

В WordPress и других CMS такое предупреждение часто вызывает плагин или тема с пробелом перед <?php в functions.php. Строка из текста ошибки указывает на файл: откройте его и очистите. Для временного обхода переименуйте папку плагина и проверьте, пропала ли ошибка.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.