diff --git a/README.TXT b/README.TXT
index 1856e0e..1946612 100644
--- a/README.TXT
+++ b/README.TXT
@@ -168,6 +168,8 @@ $conf['fast_404_string_whitelisting'] = array('cdn/farfuture', '/advagg_');
 # However, some cases (usually when checking paths for Drupal pages) you may want to show a regular 404 error. In this case you can
 # specify a URL to another page and it will be read and displayed (it can't be redirected to because we have to give a 30x header to
 # do that. This page needs to be in your docroot.
+# To enable multi-language error pages, add a "[lang]" token to the file path (e.g. 404_[lang].htm). The default
+# language must be in a file with an empty token replacement (e.g. 404_.htm).
 #$conf['fast_404_HTML_error_page'] = './my_page.html';
 
 # By default the custom 404 page is only loaded for path checking. Load it for all 404s with the below option set to TRUE
diff --git a/fast_404.inc b/fast_404.inc
index 9e7aef0..771d326 100644
--- a/fast_404.inc
+++ b/fast_404.inc
@@ -1,5 +1,109 @@
 <?php
 
+/**
+ * Get a PDO connection for use before DRUPAL_BOOTSTRAP_DATABASE.
+ *
+ * @param $close
+ *   Close any opened connection.
+ * @return PDO|NULL
+ */
+function _fast_404_pdo($close = FALSE) {
+  global $databases;
+  static $pdo = NULL;
+
+  if ($close) {
+    if (isset($pdo)) {
+      $pdo = NULL;
+    }
+    return NULL;
+  }
+
+  if (!isset($pdo) && isset($databases['default']['default']) && is_array($databases['default']['default'])) {
+    $db = $databases['default']['default'];
+    switch ($db['driver']) {
+      case 'mysql':
+      case 'pgsql':
+        $pdo = new PDO($db['driver'] . ':host=' . $db['host'] . ';dbname=' . $db['database'], $db['username'], $db['password']);
+        break;
+      case 'sqlite':
+        $pdo = new PDO($db['driver'] . ':' . $db['database']);
+        break;
+      default:
+        // The db driver is not one supported by core.
+        break;
+    }
+  }
+
+  return $pdo;
+}
+
+/**
+ * @return string
+ */
+function _fast_404_lang() {
+  static $prefix = NULL;
+
+  if (isset($prefix)) {
+    return $prefix;
+  }
+
+  if (function_exists('db_query')) {
+    $prefix = _fast_404_lang_drupal();
+  }
+  else {
+    $prefix = _fast_404_lang_pdo();
+  }
+
+  return $prefix;
+}
+
+/**
+ * Parse the language for the request using a PDO database connection.
+ */
+function _fast_404_lang_pdo() {
+
+  $pdo = _fast_404_pdo();
+  if (!isset($pdo)) {
+    return '';
+  }
+
+  // Act only when locale is enabled
+  $stmt = $pdo->prepare("SELECT status FROM system WHERE name='locale'");
+  $stmt->execute();
+  $locale = $stmt->fetchObject();
+  // TODO: Need to actually check if url negotiator is enabled
+  if ($locale && $locale->status == 1) {
+    $path_parts = explode('/', $_GET['q']);
+    $locale_stmt = $pdo->prepare("SELECT prefix FROM languages WHERE enabled = 1 AND prefix = ?");
+    $locale_stmt->execute(array($path_parts[0]));
+    $locale_item = $locale_stmt->fetchObject();
+    if (!empty($locale_item->prefix)) {
+      return $locale_item->prefix;
+    }
+  }
+
+  return '';
+}
+
+/**
+ * Parse the language for the request using Drupal's Database API.
+ */
+function _fast_404_lang_drupal() {
+
+  // Act only when locale is enabled
+  // TODO: Need to actually check if url negotiator is enabled
+  if (drupal_multilingual()) {
+    $path_parts = explode('/', $_GET['q']);
+    $prefix = db_query("SELECT prefix FROM {languages} WHERE enabled = 1 AND prefix = ?", array($path_parts[0]));
+    $lang_prefix = $prefix->fetchObject();
+    if (!empty($lang_prefix)) {
+      return $lang_prefix->prefix;
+    }
+  }
+
+  return '';
+}
+
 function fast_404_ext_check() {
 
   // Check to see if Fast 404 checks are disabled.
@@ -128,19 +232,14 @@ function fast_404_validate_path_drupal() {
     }
   }
 
-  // Act only when locale is enabled.
-  // TODO: Need to actually check if url negotiator is enabled.
-  if (db_query("SELECT status FROM {system} WHERE type = 'module' AND name = 'locale' AND status = 1")->fetchField()) {
-    $prefixes = db_query("SELECT prefix FROM {languages} WHERE enabled = 1 AND prefix != ''");
-    $lang_prefixes = $prefixes->fetchCol();
+  $query = $_GET['q'];
 
-    $path_parts = explode('/', $query);
-    if (in_array($path_parts[0], $lang_prefixes)) {
-      if (count($path_parts) == 1) {
-        return TRUE;
-      }
-      $query = substr($query, strlen($path_parts[0]) + 1);
+  $lang_prefix = _fast_404_lang();
+  if (!empty($lang_prefix)) {
+    if ($query == $lang_prefix) {
+      return TRUE;
     }
+    $query = substr($query, strlen($lang_prefix) + 1);
   }
 
   $sql = "SELECT path FROM {menu_router} WHERE :path LIKE CONCAT(path, '%')";
@@ -163,54 +262,24 @@ function fast_404_validate_path_drupal() {
  * @return bool
  */
 function fast_404_validate_path_sql() {
-  global $databases;
 
-  // Databases aren't set. They need to be set to work.
-  if (!isset($databases) || !is_array($databases['default']['default'])) {
-    // We can't check this URL here. Return TRUE to let Drupal continue
-    // bootstrapping.
+  $pdo = _fast_404_pdo();
+  if (!isset($pdo)) {
+    // Database is not set, or unable to connect. Return TRUE to let Drupal
+    // continue bootstrapping.
     return TRUE;
   }
 
-  $db = $databases['default']['default'];
-  // PDO supports any database driver Drupal does and more.
-  switch ($db['driver']) {
-    case 'mysql':
-    case 'pgsql':
-      $pdo = new PDO($db['driver'] . ':host=' . $db['host'] . ';dbname=' . $db['database'], $db['username'], $db['password']);
-      break;
-
-    case 'sqlite':
-      $pdo = new PDO($db['driver'] . ':' . $db['database']);
-      break;
-
-    default:
-      // The db driver is not supported by core therefore we allow it through.
-      return TRUE;
-    break;
-  }
-
   $query = $_GET['q'];
-  // Act only when locale is enabled.
-  $stmt = $pdo->prepare("SELECT status FROM system WHERE name='locale'");
-  $stmt->execute();
-  $locale = $stmt->fetchObject();
-  // TODO: Need to actually check if url negotiator is enabled.
-  if ($locale && $locale->status == 1) {
-    $lang_prefixes = array();
-    $locale_stmt = $pdo->prepare("SELECT prefix FROM languages WHERE enabled = 1 AND prefix != ''");
-    $locale_stmt->execute();
-    while ($locale_item = $locale_stmt->fetchObject()) {
-      $lang_prefixes[] = $locale_item->prefix;
-    }
-    $path_parts = explode('/', $query);
-    if (in_array($path_parts[0], $lang_prefixes)) {
-      if (count($path_parts) == 1) {
-        return TRUE;
-      }
-      $query = substr($query, strlen($path_parts[0]) + 1);
+
+  $lang_prefix = _fast_404_lang();
+  if (!empty($lang_prefix)) {
+    if ($query == $lang_prefix) {
+      return TRUE;
     }
+    $query = substr($query, strlen($lang_prefix) + 1);
   }
+
   // Check if redirect module is installed.
   $stmt = $pdo->prepare("SELECT status FROM system WHERE name = 'redirect'");
   $stmt->execute();
@@ -255,13 +324,26 @@ function fast_404_error_return($load_html = FALSE, $return_gone = FALSE) {
   }
 
   // If a file is set to provide us with fast_404 joy, load it.
-  if (($load_html || variable_get('fast_404_HTML_error_all_paths', FALSE))
-          && file_exists(variable_get('fast_404_HTML_error_page', FALSE))) {
-    $fast_404_html = @file_get_contents(variable_get('fast_404_HTML_error_page', FALSE));
+  if ($load_html || variable_get('fast_404_HTML_error_all_paths', FALSE)) {
+
+    $error_page = variable_get('fast_404_HTML_error_page', FALSE);
+    $lang_prefix = _fast_404_lang();
+    $error_page_processed = str_replace('[lang]', $lang_prefix, $error_page);
+    if (file_exists($error_page_processed)) {
+      $fast_404_html = @file_get_contents($error_page_processed);
+    }
+    if (!empty($lang_prefix) && empty($fast_404_html)) {
+      // Try to load the default language version, if the requested language
+      // was not available.
+      $error_page_processed = str_replace('[lang]', '', $error_page);
+      if (file_exists($error_page_processed)) {
+        $fast_404_html = @file_get_contents($error_page_processed);
+      }
+    }
   }
 
-  // If we don't have fast 404 html yet, use the default.
-  if (!isset($fast_404_html) || empty($fast_404_html)) {
+  // If we don't have fast 404 html yet, use the default
+  if (empty($fast_404_html)) {
     $fast_404_html = variable_get('fast_404_html', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>');
   }
   print strtr($fast_404_html, array('@path' => check_plain(request_uri())));
diff --git a/fast_404.module b/fast_404.module
index c1e43bc..1ae4bc5 100644
--- a/fast_404.module
+++ b/fast_404.module
@@ -31,3 +31,11 @@ function fast_404_boot() {
   // If the path is invalid then return the Fast 404 html.
   fast_404_path_check();
 }
+
+/**
+ * Implements hook_init().
+ */
+function fast_404_init() {
+  // Close the PDO database connection if checks were performed in settings.php.
+  _fast_404_pdo(TRUE);
+}
