diff --git a/lib/base.php b/lib/base.php
index 73553ff6417c13202b6c11b7dff30e65f62e40ba..cc710fc7207e553b89da26b47980f07670caa2a3 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -518,6 +518,7 @@ class OC {
 					echo $error['hint'] . "\n\n";
 				}
 			} else {
+				OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
 				OC_Template::printGuestPage('', 'error', array('errors' => $errors));
 			}
 			exit;
diff --git a/lib/private/response.php b/lib/private/response.php
index 71c538fb31137bc1eb306eab9c63eb3a333a4f20..983c682bf3fb9a85d991c8fc83645fd28f02ae56 100644
--- a/lib/private/response.php
+++ b/lib/private/response.php
@@ -12,6 +12,7 @@ class OC_Response {
 	const STATUS_TEMPORARY_REDIRECT = 307;
 	const STATUS_NOT_FOUND = 404;
 	const STATUS_INTERNAL_SERVER_ERROR = 500;
+	const STATUS_SERVICE_UNAVAILABLE = 503;
 
 	/**
 	* @brief Enable response caching by sending correct HTTP headers
@@ -74,6 +75,9 @@ class OC_Response {
 			case self::STATUS_INTERNAL_SERVER_ERROR;
 				$status = $status . ' Internal Server Error';
 				break;
+			case self::STATUS_SERVICE_UNAVAILABLE;
+				$status = $status . ' Service Unavailable';
+				break;
 		}
 		header($protocol.' '.$status);
 	}
diff --git a/lib/private/setup.php b/lib/private/setup.php
index 0d5bf424b332e74e11284bd41eae0bd067b830e4..b1061b3a25b7c351a66dafbb3211901b132ac4fb 100644
--- a/lib/private/setup.php
+++ b/lib/private/setup.php
@@ -106,6 +106,10 @@ class OC_Setup {
 			//guess what this does
 			OC_Installer::installShippedApps();
 
+			// create empty file in data dir, so we can later find
+			// out that this is indeed an ownCloud data directory
+			file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/.ocdata', '');
+
 			//create htaccess files for apache hosts
 			if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) {
 				self::createHtaccess();
diff --git a/lib/private/updater.php b/lib/private/updater.php
index 1354f3fd2f8edbb81cb7612a37b026aa95c064f8..18864c17ec9415706280f225089ca6b8915fdf1d 100644
--- a/lib/private/updater.php
+++ b/lib/private/updater.php
@@ -102,6 +102,11 @@ class Updater extends BasicEmitter {
 		}
 		$this->emit('\OC\Updater', 'maintenanceStart');
 
+		// create empty file in data dir, so we can later find
+		// out that this is indeed an ownCloud data directory
+		// (in case it didn't exist before)
+		file_put_contents(\OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
+
 		/*
 		 * START CONFIG CHANGES FOR OLDER VERSIONS
 		 */
diff --git a/lib/private/util.php b/lib/private/util.php
index fc78566e45652615091210b7f159d6f7c7e3dcfa..70dadb1befdee6c03ee8c80b709ebc4b0e11e79a 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -290,13 +290,19 @@ class OC_Util {
 	 * @return array arrays with error messages and hints
 	 */
 	public static function checkServer() {
+		$errors = array();
+		$CONFIG_DATADIRECTORY = OC_Config::getValue('datadirectory', OC::$SERVERROOT . '/data');
+
+		if (!\OC::needUpgrade() && OC_Config::getValue('installed', false)) {
+			// this check needs to be done every time
+			$errors = self::checkDataDirectoryValidity($CONFIG_DATADIRECTORY);
+		}
+
 		// Assume that if checkServer() succeeded before in this session, then all is fine.
 		if(\OC::$session->exists('checkServer_suceeded') && \OC::$session->get('checkServer_suceeded')) {
-			return array();
+			return $errors;
 		}
 
-		$errors = array();
-
 		$defaults = new \OC_Defaults();
 
 		$webServerRestart = false;
@@ -341,7 +347,6 @@ class OC_Util {
 					);
 			}
 		}
-		$CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" );
 		// Create root dir.
 		if(!is_dir($CONFIG_DATADIRECTORY)) {
 			$success=@mkdir($CONFIG_DATADIRECTORY);
@@ -540,6 +545,25 @@ class OC_Util {
 		return $errors;
 	}
 
+	/**
+	 * Check that the data directory exists and is valid by
+	 * checking the existence of the ".ocdata" file.
+	 *
+	 * @param string $dataDirectory data directory path
+	 * @return bool true if the data directory is valid, false otherwise
+	 */
+	public static function checkDataDirectoryValidity($dataDirectory) {
+		$errors = array();
+		if (!file_exists($dataDirectory.'/.ocdata')) {
+			$errors[] = array(
+				'error' => 'Data directory (' . $dataDirectory . ') is invalid',
+				'hint' => 'Please check that the data directory contains a file' .
+					' ".ocdata" in its root.'
+			);
+		}
+		return $errors;
+	}
+
 	/**
 	 * @return void
 	 */
diff --git a/tests/lib/utilcheckserver.php b/tests/lib/utilcheckserver.php
new file mode 100644
index 0000000000000000000000000000000000000000..155d617c4ade74c40565c462b07e6c8a2af23c57
--- /dev/null
+++ b/tests/lib/utilcheckserver.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+/**
+ * Tests for server check functions
+ */
+class Test_Util_CheckServer extends PHPUnit_Framework_TestCase {
+
+	private $datadir;
+
+	public function setUp() {
+		$this->datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data');
+
+		file_put_contents($this->datadir . '/.ocdata', '');
+	}
+
+	public function tearDown() {
+		// clean up
+		@unlink($this->datadir . '/.ocdata');
+	}
+
+	/**
+	 * Test that checkServer() returns no errors in the regular case.
+	 */
+	public function testCheckServer() {
+		$result = \OC_Util::checkServer();
+		$this->assertEmpty($result);
+	}
+
+	/**
+	 * Test that checkServer() does not check the data dir validity
+	 * when the server is not installed yet (else the setup cannot
+	 * be run...)
+	 */
+	public function testCheckServerSkipDataDirValidityOnSetup() {
+		// simulate old version that didn't have it
+		unlink($this->datadir . '/.ocdata');
+
+		$session = \OC::$server->getSession();
+		$oldInstalled = \OC_Config::getValue('installed', false);
+
+		// simulate that the server isn't setup yet
+		\OC_Config::setValue('installed', false);
+
+		// even though ".ocdata" is missing, the error isn't
+		// triggered to allow setup to run
+		$result = \OC_Util::checkServer();
+		$this->assertEmpty($result);
+
+		// restore config
+		\OC_Config::setValue('installed', $oldInstalled);
+	}
+
+	/**
+	 * Test that checkServer() does not check the data dir validity
+	 * when an upgrade is required (else the upgrade cannot be
+	 * performed...)
+	 */
+	public function testCheckServerSkipDataDirValidityOnUpgrade() {
+		// simulate old version that didn't have it
+		unlink($this->datadir . '/.ocdata');
+
+		$session = \OC::$server->getSession();
+		$oldCurrentVersion = $session->get('OC_Version');
+		$oldInstallVersion = \OC_Config::getValue('version', '0.0.0');
+
+		// upgrade condition to simulate needUpgrade() === true
+		$session->set('OC_Version', array(6, 0, 0, 2));
+		\OC_Config::setValue('version', '6.0.0.1');
+
+		// even though ".ocdata" is missing, the error isn't
+		// triggered to allow for upgrade
+		$result = \OC_Util::checkServer();
+		$this->assertEmpty($result);
+
+		// restore versions
+		$session->set('OC_Version', $oldCurrentVersion);
+		\OC_Config::setValue('version', $oldInstallVersion);
+	}
+
+	/**
+	 * Test that checkDataDirectoryValidity returns no error
+	 * when ".ocdata" is present.
+	 */
+	public function testCheckDataDirValidity() {
+		$result = \OC_Util::checkDataDirectoryValidity($this->datadir);
+		$this->assertEmpty($result);
+	}
+
+	/**
+	 * Test that checkDataDirectoryValidity and checkServer 
+	 * both return an error when ".ocdata" is missing.
+	 */
+	public function testCheckDataDirValidityWhenFileMissing() {
+		unlink($this->datadir . '/.ocdata');
+		$result = \OC_Util::checkDataDirectoryValidity($this->datadir);
+		$this->assertEquals(1, count($result));
+
+		$result = \OC_Util::checkServer();
+		$this->assertEquals(1, count($result));
+	}
+
+}
diff --git a/tests/testcleanuplistener.php b/tests/testcleanuplistener.php
index 299a589ef4ecff89e8f066bea836ce9e4a7aa6e3..2083ffce67c542fba35cedb13289874bcb235fa5 100644
--- a/tests/testcleanuplistener.php
+++ b/tests/testcleanuplistener.php
@@ -83,6 +83,7 @@ class TestCleanupListener implements PHPUnit_Framework_TestListener {
 		$knownEntries = array(
 			'owncloud.log' => true,
 			'owncloud.db' => true,
+			'.ocdata' => true,
 			'..' => true,
 			'.' => true
 		);
diff --git a/version.php b/version.php
index 470aa8950725a38b75f3fb7499385a92c26f9d78..5e5fa22cf8bee318c820fe7426d9016ad96534d8 100644
--- a/version.php
+++ b/version.php
@@ -1,7 +1,7 @@
 <?php
 
 // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel when updating major/minor version number.
-$OC_Version=array(6, 90, 0, 1);
+$OC_Version=array(6, 90, 0, 2);
 
 // The human readable string
 $OC_VersionString='7.0 pre alpha';