phacility/phabricator · error · Exception
Failed to poll mysqli connection!
Error message
Failed to poll mysqli connection!
What it means
In async mode, the query was dispatched with MYSQLI_ASYNC and the driver then waited with mysqli::poll(); poll() returned false, meaning the poll syscall itself failed (a mysqlnd-level error), which is distinct from a timeout (0) or success. Because the link's state is now unknown, the driver closes the connection before throwing this generic Exception — the query may or may not still be running server-side.
Source
Thrown at src/infrastructure/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php:152
protected function rawQuery($raw_query) {
$conn = $this->requireConnection();
$time_limit = $this->getQueryTimeout();
// If we have a query time limit, run this query synchronously but use
// the async API. This allows us to kill queries which take too long
// without requiring any configuration on the server side.
if ($time_limit && $this->supportsAsyncQueries()) {
$conn->query($raw_query, MYSQLI_ASYNC);
$read = array($conn);
$error = array($conn);
$reject = array($conn);
$result = mysqli::poll($read, $error, $reject, $time_limit);
if ($result === false) {
$this->closeConnection();
throw new Exception(
pht('Failed to poll mysqli connection!'));
} else if ($result === 0) {
$this->closeConnection();
throw new AphrontQueryTimeoutQueryException(
pht(
'Query timed out after %s second(s)!',
new PhutilNumber($time_limit)));
}
return @$conn->reap_async_query();
}
$trap = new PhutilErrorTrap();
$result = @$conn->query($raw_query);
$err = $trap->getErrorsAsString();
$trap->destroy();View on GitHub (pinned to 5720a38cfe)
Solutions
- Treat it as a lost connection: the object already closed the link, so re-establish the connection and retry the query once with backoff
- Check server-side health at the same moment: MySQL error log, dmesg/network errors, whether someone ran KILL
- If it recurs deterministically for one query, run that query without a time limit (synchronous path) to obtain the real underlying error
- Ensure the operation is idempotent before retrying, since the original query may have committed
Defensive patterns
Strategy: retry
Try / catch
// The driver already closed the connection; re-establish and retry once:
try {
$result = queryfx_all($conn_w, '%s', $sql);
} catch (Exception $ex) {
// 'Failed to poll mysqli connection!' => link state unknown.
$conn_w = $dao->establishConnection('w');
$result = queryfx_all($conn_w, '%s', $sql); // only if idempotent!
} Prevention
- Make async-path queries idempotent (or guarded by a re-check) because the first attempt may have committed server-side
- Keep query time limits sane so the async path is not entered casually for every statement
- Watch MySQL error logs for KILLs/restarts that coincide with poll failures
- If one query deterministically triggers it, reproduce synchronously (no time limit) to get the real error
When it happens
Trigger: Executing a query with a nonzero per-query time limit (which selects the async path) while the connection breaks: server killed the session (KILL, restart), socket error, network partition, or a mysqlnd bug. Any poll() false maps here.
Common situations: Long-running queries under aggressive query timeouts during load spikes; DB failover mid-query; flaky container networking; MySQL restarting under the client.
Related errors
- #%d: %s
- 2006
- About to call new %s, but the PHP MySQLi extension is not av
- Query timed out after %s second(s)!
- There are some results left in the result set.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/f3bda326fe686bec.
Report an issue: GitHub.