symfony/http-foundation · error · DomainException
SQLite does not support advisory locks.
Error message
SQLite does not support advisory locks.
What it means
This DomainException is thrown by PdoSessionHandler::doAdvisoryLock() when the handler is configured with lock_mode LOCK_ADVISORY (lock_mode option = 3) and the underlying PDO driver is 'sqlite'. SQLite has no advisory-lock functions (no GET_LOCK / pg_advisory_lock equivalent), so the handler refuses to operate instead of providing weaker guarantees. The error surfaces when a read (doRead) triggers the advisory lock acquisition.
Solutions
- Remove the 'lock_mode' option (or set it to PdoSessionHandler::LOCK_NONE) when using a sqlite connection — SQLite serializes writes via its own file lock, so advisory locking is unnecessary.
- Switch the session store to the production database (mysql/pgsql DSN) if advisory locking semantics are genuinely needed.
- Use PdoSessionHandler::LOCK_TRANSACTIONAL instead, which is supported for sqlite (locking is done via the transaction: 'we already locked when starting transaction').
- Differentiate config per environment: define lock_mode only for drivers that support advisory locks (mysql, pgsql).
Example fix
// before $handler = new PdoSessionHandler($pdo, ['lock_mode' => PdoSessionHandler::LOCK_ADVISORY]); // after (sqlite) $handler = new PdoSessionHandler($pdo, ['lock_mode' => PdoSessionHandler::LOCK_TRANSACTIONAL]);
Defensive patterns
Strategy: validation
Validate before calling
$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
if ('sqlite' === $driver && ($options['lock_mode'] ?? null) === PdoSessionHandler::LOCK_ADVISORY) {
unset($options['lock_mode']); // or use LOCK_TRANSACTIONAL
} Try / catch
try {
$session->start();
} catch (\DomainException $e) {
if (str_contains($e->getMessage(), 'does not support advisory locks')) {
// rebuild handler with LOCK_TRANSACTIONAL or LOCK_NONE
} else {
throw $e;
}
} Prevention
- Never set LOCK_ADVISORY for sqlite DSNs; gate lock_mode on driver name
- Use environment-specific session handler config (dev sqlite vs prod mysql/pgsql)
- Remember sqlite needs no advisory lock — its file locking already serializes writers
When it happens
Trigger: Constructing PdoSessionHandler with ['lock_mode' => PdoSessionHandler::LOCK_ADVISORY] (or db_connection options setting advisory locking) on a PDO connection whose driver is sqlite, then opening a session (session_start() -> read() -> doRead() -> doAdvisoryLock()).
Common situations: Local dev or test environments using sqlite:// DSN while the session config was written for MySQL/PostgreSQL production (lock_mode carried over from prod config); copying a framework bundle config with LOCK_ADVISORY into a sqlite-based project; fixture/test databases using PDO sqlite.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Advisory locks are currently not implemented for PDO driver
- Transactional locks are currently not implemented for PDO…
- " " requires PDO error mode attribute be set to throw…
- You must provide the "database" and "collection" option for…
- Invalid argument $savePath
AI-assisted analysis of symfony/http-foundation@5aea19cd67 (2026-09-13).
Data as JSON: /api/errors/da97c66e39c3a4ac.
Report an issue: GitHub.
Appendix: source
Thrown at Session/Storage/Handler/PdoSessionHandler.php:805
$stmt->execute();
$releaseStmt = $this->pdo->prepare('SELECT pg_advisory_unlock(:key1, :key2)');
$releaseStmt->bindValue(':key1', $sessionInt1, \PDO::PARAM_INT);
$releaseStmt->bindValue(':key2', $sessionInt2, \PDO::PARAM_INT);
} else {
$sessionBigInt = $this->convertStringToInt($sessionId);
$stmt = $this->pdo->prepare('SELECT pg_advisory_lock(:key)');
$stmt->bindValue(':key', $sessionBigInt, \PDO::PARAM_INT);
$stmt->execute();
$releaseStmt = $this->pdo->prepare('SELECT pg_advisory_unlock(:key)');
$releaseStmt->bindValue(':key', $sessionBigInt, \PDO::PARAM_INT);
}
return $releaseStmt;
case 'sqlite':
throw new \DomainException('SQLite does not support advisory locks.');
default:
throw new \DomainException(\sprintf('Advisory locks are currently not implemented for PDO driver "%s".', $this->driver));
}
}
/**
* Encodes the first 4 (when PHP_INT_SIZE == 4) or 8 characters of the string as an integer.
*
* Keep in mind, PHP integers are signed.
*/
private function convertStringToInt(string $string): int
{
if (4 === \PHP_INT_SIZE) {
return (\ord($string[3]) << 24) + (\ord($string[2]) << 16) + (\ord($string[1]) << 8) + \ord($string[0]);
}
$int1 = (\ord($string[7]) << 24) + (\ord($string[6]) << 16) + (\ord($string[5]) << 8) + \ord($string[4]);
$int2 = (\ord($string[3]) << 24) + (\ord($string[2]) << 16) + (\ord($string[1]) << 8) + \ord($string[0]);View on GitHub (pinned to 5aea19cd67)