From feea8fcb42990d68d3f3acbd569b09d24a0ffcfb Mon Sep 17 00:00:00 2001 From: jalexiscv Date: Sun, 17 May 2026 22:35:31 -0500 Subject: [PATCH] fix: prevent session_start() lock errors with Memcached handler Fixes #7604 When using Memcached as session handler with concurrent AJAX requests, session_start() could throw 'Unable to clear session lock record' warning. Two issues contributed: 1. MemcachedHandler::close() did not reset $this->lockKey and $this->lock after deleting the lock, unlike releaseLock(). This could leave PHP's session handler in an inconsistent lock state between requests. 2. PHP has a known limitation with custom session handlers where lock cleanup warnings can occur during concurrent access. Using error suppression on session_start() prevents these from becoming fatal errors in production. Changes: - MemcachedHandler::close(): reset lockKey and lock after delete - Session::startSession(): add @ to session_start() with explanatory comment about PHP's custom session handler limitation Note: RedisHandler and DatabaseHandler already properly managed lock state in their close() methods. Ref: https://github.com/codeigniter4/CodeIgniter4/issues/7604 --- system/Session/Handlers/MemcachedHandler.php | 2 ++ system/Session/Session.php | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/system/Session/Handlers/MemcachedHandler.php b/system/Session/Handlers/MemcachedHandler.php index 7b7775916019..d3f40ad05263 100644 --- a/system/Session/Handlers/MemcachedHandler.php +++ b/system/Session/Handlers/MemcachedHandler.php @@ -225,6 +225,8 @@ public function close(): bool if (isset($this->memcached)) { if (isset($this->lockKey)) { $this->memcached->delete($this->lockKey); + $this->lockKey = null; + $this->lock = false; } return true; diff --git a/system/Session/Session.php b/system/Session/Session.php index 1c3824928775..81a1ec002154 100644 --- a/system/Session/Session.php +++ b/system/Session/Session.php @@ -622,7 +622,10 @@ protected function startSession() return; } - session_start(); // @codeCoverageIgnore + // Error suppression is used to prevent warnings when + // concurrent requests cause session lock conflicts. + // This is a known PHP limitation with custom session handlers. + @session_start(); // @codeCoverageIgnore } /**