diff --git a/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php b/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php
--- a/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php
+++ b/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php
@@ -64,6 +64,18 @@
       $conn->options(MYSQLI_OPT_CONNECT_TIMEOUT, $timeout);
     }
 
+    // See T13238. Attempt to prevent "LOAD DATA LOCAL INFILE", which allows a
+    // malicious server to ask the client for any file.
+
+    // NOTE: See T13238. This option does not appear to ever have any effect.
+    // Only the PHP level configuration of "mysqli.allow_local_infile" is
+    // effective in preventing "LOAD DATA LOCAL INFILE". It appears that the
+    // configuration option may overwrite the local option? Set the local
+    // option to the desired (safe) value anyway in case this starts working
+    // properly in some future version of PHP/MySQLi.
+
+    $conn->options(MYSQLI_OPT_LOCAL_INFILE, 0);
+
     if ($this->getPersistent()) {
       $host = 'p:'.$host;
     }
@@ -122,7 +134,36 @@
       return @$conn->reap_async_query();
     }
 
-    return @$conn->query($raw_query);
+    $trap = new PhutilErrorTrap();
+
+    $result = @$conn->query($raw_query);
+
+    $err = $trap->getErrorsAsString();
+    $trap->destroy();
+
+    // See T13238 and PHI1014. Sometimes, the call to "$conn->query()" may fail
+    // without setting an error code on the connection. One way to reproduce
+    // this is to use "LOAD DATA LOCAL INFILE" with "mysqli.allow_local_infile"
+    // disabled.
+
+    // If we have no result and no error code, raise a synthetic query error
+    // with whatever error message was raised as a local PHP warning.
+
+    if (!$result) {
+      $error_code = $this->getErrorCode($conn);
+      if (!$error_code) {
+        if (strlen($err)) {
+          $message = $err;
+         } else {
+          $message = pht(
+            'Call to "mysqli->query()" failed, but did not set an error '.
+            'code or emit an error message.');
+        }
+        $this->throwQueryCodeException(777777, $message);
+      }
+    }
+
+    return $result;
   }
 
   protected function rawQueries(array $raw_queries) {