Introduction

PHP's unserialize() function is used internally to decode session data stored as serialized strings. When the session data becomes corrupted -- due to interrupted writes, encoding issues, or mixing session handlers -- unserialize fails with "Error at offset" or "Unexpected end of serialized data" errors.

This causes users to be unexpectedly logged out, lose their cart contents, or encounter fatal errors on every page load.

Symptoms

  • PHP throws "unserialize(): Error at offset X of Y bytes"
  • Session data appears to be reset on every request
  • Error log shows "Failed to decode session data" warnings

Common Causes

  • Session file was truncated during a crash or disk full condition
  • Special characters in session data corrupt the serialization format
  • Mixed PHP versions reading/writing session data with different serialization formats

Step-by-Step Fix

  1. 1.Handle unserialize errors gracefully: Catch corrupted session data and start fresh.
  2. 2.```php
  3. 3.<?php
  4. 4.set_error_handler(function ($errno, $errstr) {
  5. 5.if (strpos($errstr, 'unserialize()') !== false) {
  6. 6.// Destroy corrupted session and start fresh
  7. 7.session_destroy();
  8. 8.session_start();
  9. 9.return true; // Suppress the error
  10. 10.}
  11. 11.return false; // Let other errors through
  12. 12.});

session_start(); restore_error_handler(); ```

  1. 1.Switch to JSON-based session serialization: More robust than PHP's serialize format.
  2. 2.```php
  3. 3.<?php
  4. 4.// In php.ini or at runtime:
  5. 5.ini_set('session.serialize_handler', 'php_serialize');
  6. 6.// Or use the more robust php_serialize instead of the default 'php' handler

session_start(); $_SESSION['user_id'] = 123; $_SESSION['cart'] = ['item1', 'item2']; ```

  1. 1.Migrate to Redis session storage: More reliable than file-based sessions.
  2. 2.```php
  3. 3.<?php
  4. 4.// Configure Redis as session handler:
  5. 5.ini_set('session.save_handler', 'redis');
  6. 6.ini_set('session.save_path', 'tcp://127.0.0.1:6379');
  7. 7.ini_set('session.serialize_handler', 'php_serialize');

session_start();

// Verify session works: $_SESSION['test'] = 'value'; echo session_id(); ```

  1. 1.Clean up corrupted session files: Remove broken session files from disk.
  2. 2.```bash
  3. 3.# Find and remove corrupted session files:
  4. 4.find /var/lib/php/sessions -name "sess_*" -exec php -r '
  5. 5.$f = $argv[1];
  6. 6.$data = file_get_contents($f);
  7. 7.if (@unserialize($data) === false && $data !== "") {
  8. 8.echo "Corrupted: $f\n";
  9. 9.unlink($f);
  10. 10.}
  11. 11.' {} \;
  12. 12.`

Prevention

  • Use php_serialize as the session serialization handler
  • Store sessions in Redis or a database for reliability
  • Implement session validation checks at application startup
  • Monitor disk space to prevent session file truncation