Ffile2fix
Sign in Get started

How to fix "session_start(): Failed to read session data"

Warning: session_start(): open(/var/lib/php/sessions/sess_k3j2h1g0f9e8d7c6b5a4, O_RDWR) failed: Permission denied (13) in /home/user/public_html/login.php on line 3
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /home/user/public_html/login.php on line 3

PHP stores session data in the location set by session.save_path, usually a folder on disk. If that folder is missing, full, or not writable by the PHP user, or a Redis session server is unreachable, session_start() fails and logins stop working. If the message mentions headers, output was sent before the session started.

Also appears as: Warning: session_start(): open(/tmp/sess_abc123, O_RDWR) failed: No such file or directory (2) · Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/var/lib/php/sessions) · Warning: session_start(): Session cannot be started after headers have already been sent · session_start(): Failed to read session data: redis (path: tcp://127.0.0.1:6379)

Common causes

  • session.save_path points to a folder that does not exist
  • The PHP user (www-data, nginx or your account user) cannot write to the session folder
  • The disk or inode quota is full, so new session files cannot be created
  • A Redis or Memcached session handler is configured but the service is down
  • Output was sent before session_start(), causing the headers-already-sent variant
  • A per-site PHP-FPM pool sets a different save path than the one that exists

How to fix it

  1. Find the active save path. Check session.save_path and session.save_handler in phpinfo(). The path in the error is the folder PHP is trying to use.
  2. Create the folder with the right owner. Create it if missing and give it to the PHP user, for example sudo mkdir -p /var/lib/php/sessions && sudo chown www-data:www-data /var/lib/php/sessions && sudo chmod 1733 /var/lib/php/sessions. 1733 lets PHP create files but not list other users' sessions; use 700 for a folder used by a single site.
  3. Check disk space. Run df -h and df -i. A full disk or inode table stops new session files. Clear old sessions and check that session garbage collection or the system cleanup cron runs.
  4. Set a per-site path on shared hosting. Point sessions to a private folder outside the web root, for example session.save_path = "/home/user/tmp/sessions" in .user.ini, and create that folder with 700 permissions.
  5. Fix Redis-backed sessions. If the handler is redis, test the server with redis-cli ping and confirm the save path host and port. Restart Redis or switch back to files while you fix it.
  6. Start the session before output. If the warning mentions headers already sent, call session_start() at the very top of the script before any echo, HTML or whitespace.

Private session folder for one site (php.ini or .user.ini)

; .user.ini
session.save_handler = files
session.save_path = "/home/user/tmp/sessions"
session.gc_maxlifetime = 1440

# create the folder
mkdir -p /home/user/tmp/sessions && chmod 700 /home/user/tmp/sessions

How to stop it happening again

  • Keep sessions in a folder only the PHP user can access
  • Monitor disk space and inodes on servers with many sessions
  • Health-check Redis if it stores sessions
  • Call session_start() before any output

Frequently asked questions

Why do users get logged out randomly?

If session files cannot be written, each request starts a new empty session. Fix the save path permissions or disk space and logins will persist.

Should I store sessions in /tmp?

It works, but /tmp is shared and may be cleaned at any time. A dedicated folder owned by the PHP user is safer.

Why do sessions fail only after a reboot?

Some systems recreate /run or /tmp folders on boot without your custom session folder. Create it from a systemd tmpfiles rule or use a persistent path.