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

  1. Treat it as a lost connection: the object already closed the link, so re-establish the connection and retry the query once with backoff
  2. Check server-side health at the same moment: MySQL error log, dmesg/network errors, whether someone ran KILL
  3. If it recurs deterministically for one query, run that query without a time limit (synchronous path) to obtain the real underlying error
  4. 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

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


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/f3bda326fe686bec. Report an issue: GitHub.