diff --git a/phpBB/includes/search/base.php b/phpBB/includes/search/base.php
index b364dead9a..914cef9167 100644
--- a/phpBB/includes/search/base.php
+++ b/phpBB/includes/search/base.php
@@ -94,7 +94,7 @@ class phpbb_search_base
 	*
 	* @return int SEARCH_RESULT_NOT_IN_CACHE or SEARCH_RESULT_IN_CACHE or SEARCH_RESULT_INCOMPLETE
 	*/
-	function obtain_ids($search_key, &$result_count, &$id_ary, $start, $per_page, $sort_dir)
+	function obtain_ids($search_key, &$result_count, &$id_ary, &$start, $per_page, $sort_dir)
 	{
 		global $cache;
 
@@ -109,6 +109,19 @@ class phpbb_search_base
 			$reverse_ids = ($stored_ids[-2] != $sort_dir) ? true : false;
 			$complete = true;
 
+			// Change start parameter in case out of bounds
+			if ($result_count)
+			{
+				if ($start < 0)
+				{
+					$start = 0;
+				}
+				else if ($start >= $result_count)
+				{
+					$start = floor(($result_count - 1) / $per_page) * $per_page;
+				}
+			}
+
 			// change the start to the actual end of the current request if the sort direction differs
 			// from the dirction in the cache and reverse the ids later
 			if ($reverse_ids)
diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php
index 324c214e91..adaf025730 100644
--- a/phpBB/includes/search/fulltext_mysql.php
+++ b/phpBB/includes/search/fulltext_mysql.php
@@ -353,7 +353,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base
 	* @param	int			$per_page			number of ids each page is supposed to contain
 	* @return	boolean|int						total number of results
 	*/
-	public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page)
+	public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page)
 	{
 		// No keywords? No posts
 		if (!$this->search_query)
@@ -375,6 +375,11 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base
 			implode(',', $author_ary)
 		)));
 
+		if ($start < 0)
+		{
+			$start = 0;
+		}
+
 		// try reading the results from cache
 		$result_count = 0;
 		if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE)
@@ -488,16 +493,11 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base
 
 		$id_ary = array_unique($id_ary);
 
-		if (!sizeof($id_ary))
-		{
-			return false;
-		}
-
 		// if the total result count is not cached yet, retrieve it from the db
 		if (!$result_count)
 		{
-			$sql = 'SELECT FOUND_ROWS() as result_count';
-			$result = $this->db->sql_query($sql);
+			$sql_found_rows = 'SELECT FOUND_ROWS() as result_count';
+			$result = $this->db->sql_query($sql_found_rows);
 			$result_count = (int) $this->db->sql_fetchfield('result_count');
 			$this->db->sql_freeresult($result);
 
@@ -507,6 +507,21 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base
 			}
 		}
 
+		if ($start >= $result_count)
+		{
+			$start = floor(($result_count - 1) / $per_page) * $per_page;
+
+			$result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start);
+
+			while ($row = $this->db->sql_fetchrow($result))
+			{
+				$id_ary[] = (int) $row[$field];
+			}
+			$this->db->sql_freeresult($result);
+
+			$id_ary = array_unique($id_ary);
+		}
+
 		// store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page
 		$this->save_ids($search_key, implode(' ', $this->split_words), $author_ary, $result_count, $id_ary, $start, $sort_dir);
 		$id_ary = array_slice($id_ary, 0, (int) $per_page);
@@ -533,7 +548,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base
 	* @param	int			$per_page			number of ids each page is supposed to contain
 	* @return	boolean|int						total number of results
 	*/
-	public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page)
+	public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page)
 	{
 		// No author? No posts
 		if (!sizeof($author_ary))
@@ -557,6 +572,11 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base
 			$author_name,
 		)));
 
+		if ($start < 0)
+		{
+			$start = 0;
+		}
+
 		// try reading the results from cache
 		$result_count = 0;
 		if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE)
@@ -662,8 +682,8 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base
 		// retrieve the total result count if needed
 		if (!$result_count)
 		{
-			$sql = 'SELECT FOUND_ROWS() as result_count';
-			$result = $this->db->sql_query($sql);
+			$sql_found_rows = 'SELECT FOUND_ROWS() as result_count';
+			$result = $this->db->sql_query($sql_found_rows);
 			$result_count = (int) $this->db->sql_fetchfield('result_count');
 			$this->db->sql_freeresult($result);
 
@@ -673,6 +693,20 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base
 			}
 		}
 
+		if ($start >= $result_count)
+		{
+			$start = floor(($result_count - 1) / $per_page) * $per_page;
+
+			$result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start);
+			while ($row = $this->db->sql_fetchrow($result))
+			{
+				$id_ary[] = (int) $row[$field];
+			}
+			$this->db->sql_freeresult($result);
+
+			$id_ary = array_unique($id_ary);
+		}
+
 		if (sizeof($id_ary))
 		{
 			$this->save_ids($search_key, '', $author_ary, $result_count, $id_ary, $start, $sort_dir);
diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php
index 53df8348ae..c9f33054fc 100644
--- a/phpBB/includes/search/fulltext_native.php
+++ b/phpBB/includes/search/fulltext_native.php
@@ -516,7 +516,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base
 	* @param	int			$per_page			number of ids each page is supposed to contain
 	* @return	boolean|int						total number of results
 	*/
-	public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page)
+	public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page)
 	{
 		// No keywords? No posts.
 		if (empty($this->search_query))
@@ -855,10 +855,6 @@ class phpbb_search_fulltext_native extends phpbb_search_base
 		}
 		$this->db->sql_freeresult($result);
 
-		if (!sizeof($id_ary))
-		{
-			return false;
-		}
 
 		// if we use mysql and the total result count is not cached yet, retrieve it from the db
 		if (!$total_results && $is_mysql)
@@ -867,14 +863,14 @@ class phpbb_search_fulltext_native extends phpbb_search_base
 			$sql_array_copy = $sql_array;
 			$sql_array_copy['SELECT'] = 'SQL_CALC_FOUND_ROWS p.post_id ';
 
-			$sql = $this->db->sql_build_query('SELECT', $sql_array_copy);
+			$sql_calc = $this->db->sql_build_query('SELECT', $sql_array_copy);
 			unset($sql_array_copy);
 
-			$this->db->sql_query($sql);
+			$this->db->sql_query($sql_calc);
 			$this->db->sql_freeresult($result);
 
-			$sql = 'SELECT FOUND_ROWS() as total_results';
-			$result = $this->db->sql_query($sql);
+			$sql_count = 'SELECT FOUND_ROWS() as total_results';
+			$result = $this->db->sql_query($sql_count);
 			$total_results = (int) $this->db->sql_fetchfield('total_results');
 			$this->db->sql_freeresult($result);
 
@@ -884,6 +880,20 @@ class phpbb_search_fulltext_native extends phpbb_search_base
 			}
 		}
 
+		if ($start >= $total_results)
+		{
+			$start = floor(($total_results - 1) / $per_page) * $per_page;
+
+			$result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start);
+
+			while ($row = $this->db->sql_fetchrow($result))
+			{
+				$id_ary[] = (int) $row[(($type == 'posts') ? 'post_id' : 'topic_id')];
+			}
+			$this->db->sql_freeresult($result);
+
+		}
+
 		// store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page
 		$this->save_ids($search_key, $this->search_query, $author_ary, $total_results, $id_ary, $start, $sort_dir);
 		$id_ary = array_slice($id_ary, 0, (int) $per_page);
@@ -910,7 +920,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base
 	* @param	int			$per_page			number of ids each page is supposed to contain
 	* @return	boolean|int						total number of results
 	*/
-	public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page)
+	public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page)
 	{
 		// No author? No posts
 		if (!sizeof($author_ary))
@@ -1096,13 +1106,13 @@ class phpbb_search_fulltext_native extends phpbb_search_base
 		if (!$total_results && $is_mysql)
 		{
 			// Count rows for the executed queries. Replace $select within $sql with SQL_CALC_FOUND_ROWS, and run it.
-			$sql = str_replace('SELECT ' . $select, 'SELECT DISTINCT SQL_CALC_FOUND_ROWS p.post_id', $sql);
+			$sql_calc = str_replace('SELECT ' . $select, 'SELECT DISTINCT SQL_CALC_FOUND_ROWS p.post_id', $sql);
 
-			$this->db->sql_query($sql);
+			$this->db->sql_query($sql_calc);
 			$this->db->sql_freeresult($result);
 
-			$sql = 'SELECT FOUND_ROWS() as total_results';
-			$result = $this->db->sql_query($sql);
+			$sql_count = 'SELECT FOUND_ROWS() as total_results';
+			$result = $this->db->sql_query($sql_count);
 			$total_results = (int) $this->db->sql_fetchfield('total_results');
 			$this->db->sql_freeresult($result);
 
@@ -1112,6 +1122,19 @@ class phpbb_search_fulltext_native extends phpbb_search_base
 			}
 		}
 
+		if ($start >= $total_results)
+		{
+			$start = floor(($total_results - 1) / $per_page) * $per_page;
+
+			$result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start);
+
+			while ($row = $this->db->sql_fetchrow($result))
+			{
+				$id_ary[] = (int) $row[$field];
+			}
+			$this->db->sql_freeresult($result);
+		}
+
 		if (sizeof($id_ary))
 		{
 			$this->save_ids($search_key, '', $author_ary, $total_results, $id_ary, $start, $sort_dir);
diff --git a/phpBB/includes/search/fulltext_postgres.php b/phpBB/includes/search/fulltext_postgres.php
index 1475cc31d0..eeb628b18f 100644
--- a/phpBB/includes/search/fulltext_postgres.php
+++ b/phpBB/includes/search/fulltext_postgres.php
@@ -343,7 +343,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base
 	* @param	int			$per_page			number of ids each page is supposed to contain
 	* @return	boolean|int						total number of results
 	*/
-	public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page)
+	public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page)
 	{
 		// No keywords? No posts
 		if (!$this->search_query)
@@ -371,6 +371,11 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base
 			implode(',', $author_ary)
 		)));
 
+		if ($start < 0)
+		{
+			$start = 0;
+		}
+
 		// try reading the results from cache
 		$result_count = 0;
 		if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE)
@@ -495,11 +500,6 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base
 
 		$id_ary = array_unique($id_ary);
 
-		if (!sizeof($id_ary))
-		{
-			return false;
-		}
-
 		// if the total result count is not cached yet, retrieve it from the db
 		if (!$result_count)
 		{
@@ -518,6 +518,21 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base
 
 		$this->db->sql_transaction('commit');
 
+		if ($start >= $result_count)
+		{
+			$start = floor(($result_count - 1) / $per_page) * $per_page;
+
+			$result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start);
+
+			while ($row = $this->db->sql_fetchrow($result))
+			{
+				$id_ary[] = $row[$field];
+			}
+			$this->db->sql_freeresult($result);
+
+			$id_ary = array_unique($id_ary);
+		}
+
 		// store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page
 		$this->save_ids($search_key, implode(' ', $this->split_words), $author_ary, $result_count, $id_ary, $start, $sort_dir);
 		$id_ary = array_slice($id_ary, 0, (int) $per_page);
@@ -544,7 +559,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base
 	* @param	int			$per_page			number of ids each page is supposed to contain
 	* @return	boolean|int						total number of results
 	*/
-	public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page)
+	public function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page)
 	{
 		// No author? No posts
 		if (!sizeof($author_ary))
@@ -568,6 +583,11 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base
 			$author_name,
 		)));
 
+		if ($start < 0)
+		{
+			$start = 0;
+		}
+
 		// try reading the results from cache
 		$result_count = 0;
 		if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE)
@@ -710,6 +730,20 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base
 
 		$this->db->sql_transaction('commit');
 
+		if ($start >= $result_count)
+		{
+			$start = floor(($result_count - 1) / $per_page) * $per_page;
+
+			$result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start);
+			while ($row = $this->db->sql_fetchrow($result))
+			{
+				$id_ary[] = (int) $row[$field];
+			}
+			$this->db->sql_freeresult($result);
+
+			$id_ary = array_unique($id_ary);
+		}
+
 		if (sizeof($id_ary))
 		{
 			$this->save_ids($search_key, '', $author_ary, $result_count, $id_ary, $start, $sort_dir);
diff --git a/phpBB/includes/search/fulltext_sphinx.php b/phpBB/includes/search/fulltext_sphinx.php
index 7304e70ff8..48445d0794 100644
--- a/phpBB/includes/search/fulltext_sphinx.php
+++ b/phpBB/includes/search/fulltext_sphinx.php
@@ -454,7 +454,7 @@ class phpbb_search_fulltext_sphinx
 	* @param	int			$per_page			number of ids each page is supposed to contain
 	* @return	boolean|int						total number of results
 	*/
-	public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page)
+	public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page)
 	{
 		// No keywords? No posts.
 		if (!strlen($this->search_query) && !sizeof($author_ary))
@@ -609,6 +609,25 @@ class phpbb_search_fulltext_sphinx
 			}
 		}
 
+		$result_count = $result['total_found'];
+
+		if ($start >= $result_count)
+		{
+			$start = floor(($result_count - 1) / $per_page) * $per_page;
+
+			$this->sphinx->SetLimits((int) $start, (int) $per_page, SPHINX_MAX_MATCHES);
+			$result = $this->sphinx->Query($search_query_prefix . str_replace('&quot;', '"', $this->search_query), $this->indexes);
+
+			// Could be connection to localhost:9312 failed (errno=111,
+			// msg=Connection refused) during rotate, retry if so
+			$retries = SPHINX_CONNECT_RETRIES;
+			while (!$result && (strpos($this->sphinx->GetLastError(), "errno=111,") !== false) && $retries--)
+			{
+				usleep(SPHINX_CONNECT_WAIT_TIME);
+				$result = $this->sphinx->Query($search_query_prefix . str_replace('&quot;', '"', $this->search_query), $this->indexes);
+			}
+		}
+
 		$id_ary = array();
 		if (isset($result['matches']))
 		{
@@ -629,8 +648,6 @@ class phpbb_search_fulltext_sphinx
 			return false;
 		}
 
-		$result_count = $result['total_found'];
-
 		$id_ary = array_slice($id_ary, 0, (int) $per_page);
 
 		return $result_count;