Troubleshooting

Fix PHP session errors: save path, permissions and lost logins

Fix session_start() errors and users being logged out: session.save_path permissions, full disks, garbage collection, cookie settings, multiple servers and Redis sessions.

IntermediatecPanel hosting · Linux VPS3 min read

PHP sessions keep users logged in and carts filled between page loads. When they break you see warnings like session_start(): open(/var/lib/php/sessions/sess_..., O_RDWR) failed: Permission denied, or users are simply logged out at random. This guide covers the usual PHP session errors and their fixes.

Before you start

  • Find the active session settings: create a temporary phpinfo() page and look at the session section (session.save_handler, session.save_path, session.gc_maxlifetime, cookie settings). Delete the page afterwards.

Failed to open stream: Permission denied

PHP cannot write session files to session.save_path. On a VPS, make it writable by the PHP-FPM user:

chown root:www-data /var/lib/php/sessions && chmod 1733 /var/lib/php/sessions

(Mode 1733 lets PHP create files but not list other users' sessions.) For a per-site pool, a dedicated folder is cleaner: php_value[session.save_path] = /var/lib/php/sessions/site1 owned by that pool's user. On AlmaLinux/Rocky with SELinux, restore labels with restorecon -Rv on the folder.

No space left on device

A full disk or exhausted inodes stop session writes. Check df -h and df -i; millions of old session files can be the cause themselves.

Old sessions piling up

Debian and Ubuntu disable PHP's probabilistic garbage collection (session.gc_probability = 0) and clean sessions with a systemd timer (phpsessionclean). If you use a custom save path, that cleaner does not know about it. Add your own cron job:

17 * * * * find /var/lib/php/sessions/site1 -type f -mmin +1440 -delete

Users logged out too early

  • Lifetime: session.gc_maxlifetime (seconds) controls when idle sessions are cleaned. Frameworks often override it (Laravel SESSION_LIFETIME, WordPress uses its own auth cookies).
  • Another site cleans your sessions: sites sharing one save path with shorter lifetimes delete each other's files. Give each site its own path.
  • Cookie domain or path mismatch: switching between www and non-www creates separate cookies. Redirect to one canonical host.
  • Secure cookies over HTTP: with session.cookie_secure = 1, browsers send the cookie only over HTTPS; make sure the whole site uses HTTPS.
  • SameSite: cross-site flows (payment gateways returning via POST) may need SameSite=None; Secure for the relevant cookie.

Sessions across multiple servers

Behind a load balancer, file sessions exist only on the server that created them, so users appear logged out when routed elsewhere. Store sessions centrally in Redis:

session.save_handler = redis
session.save_path = "tcp://10.0.0.20:6379?auth=strong-password"

This needs the PHP redis extension. Frameworks offer the same through their config (Laravel SESSION_DRIVER=redis).

Session locking slows pages

File sessions are locked while a request runs, so parallel AJAX requests from one user wait for each other. Call session_write_close() as soon as your code no longer needs to write the session.

Headers already sent

session_start(): Session cannot be started after headers have already been sent means output happened before the session started; see the headers already sent guide.

Check the fix

Log in, browse several pages and confirm new session files (or Redis keys) are created and updated, and that the warning no longer appears in the error log.

PHP sessions FAQ

Where are sessions stored on cPanel?

The server manages the path per PHP version; you can change session settings in MultiPHP INI Editor or Select PHP Version options.

Files or Redis for sessions?

Files are fine on one server. Use Redis for multiple servers or very busy sites.

Is it safe to delete session files?

Deleting them logs out the affected users but causes no other damage.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.