phacility/phabricator · error · AphrontConnectionLostQueryException

#%d: %s

Error message

#%d: %s

What it means

The common wrapper Phabricator's MySQL connection layer uses to surface raw MySQL errors: the server/client error number and description are formatted as '#<errno>: <description>' and then mapped in throwCommonException() to typed query exceptions — e.g. errno 2013 (connection dropped) becomes AphrontConnectionLostQueryException. Seeing this shape means a MySQL-level failure was translated; the typed exception class and errno carry the actual diagnosis. Phabricator's workers automatically retry queries that failed with transient (connection/deadlock) exceptions.

Source

Thrown at src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:329

  protected function throwQueryException($connection) {
    if ($this->nextError) {
      $errno = $this->nextError;
      $error = pht('Simulated error.');
      $this->nextError = null;
    } else {
      $errno = $this->getErrorCode($connection);
      $error = $this->getErrorDescription($connection);
    }
    $this->throwQueryCodeException($errno, $error);
  }

  private function throwCommonException($errno, $error) {
    $message = pht('#%d: %s', $errno, $error);

    switch ($errno) {
      case 2013: // Connection Dropped
        throw new AphrontConnectionLostQueryException($message);
      case 2006: // Gone Away
        $more = pht(
          'This error may occur if your configured MySQL "wait_timeout" or '.
          '"max_allowed_packet" values are too small. This may also indicate '.
          'that something used the MySQL "KILL <process>" command to kill '.
          'the connection running the query.');
        throw new AphrontConnectionLostQueryException("{$message}\n\n{$more}");
      case 1213: // Deadlock
        throw new AphrontDeadlockQueryException($message);
      case 1205: // Lock wait timeout exceeded
        throw new AphrontLockTimeoutQueryException($message);
      case 1062: // Duplicate Key
        // NOTE: In some versions of MySQL we get a key name back here, but
        // older versions just give us a key index ("key 2") so it's not
        // portable to parse the key out of the error and attach it to the
        // exception.
        throw new AphrontDuplicateKeyQueryException($message);
      case 1044: // Access denied to database

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Identify the errno in the '#<errno>:' prefix and follow its specific remedy (2006/2013: connection; 1213: deadlock; 1205: lock timeout)
  2. If you are executing queries yourself, retry on AphrontConnectionLostQueryException with a fresh connection — the daemons already do this
  3. Check mysqld uptime/logs to see whether the server restarted at that moment
  4. For frequent idle drops, lower wait_timeout-side keepalives or enable TCP keepalives between hosts

Example fix

// before: assuming a query always succeeds
$rows = queryfx_all($conn, 'SELECT * FROM %T', $table);

// after: retry transient connection losses with a new connection
for ($attempt = 0; $attempt < 3; $attempt++) {
  try {
    $rows = queryfx_all($conn, 'SELECT * FROM %T', $table);
    break;
  } catch (AphrontConnectionLostQueryException $ex) {
    $conn = $object->establishConnection('r'); // fresh connection
  }
}
Defensive patterns

Strategy: retry

Try / catch

try {
  $rows = queryfx_all($conn, $sql);
} catch (AphrontConnectionLostQueryException $ex) {
  // transient: re-establish and retry (Phabricator workers do this for you)
  $conn = $object->establishConnection($mode);
  $rows = queryfx_all($conn, $sql);
}

Prevention

When it happens

Trigger: Any MySQL statement failure while the connection is severed (packet loss, restart of mysqld, proxy idle timeout) — errno 2013 'Lost connection to MySQL server during query'; also the shared prefix of the 2006/1213/1205/1062/1142 mappings emitted from the same switch.

Common situations: Long-running daemons holding idle connections cut by a firewall or load balancer; mysqld restarting under the application; network blips between web hosts and the database.

Related errors


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