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 fd2d46a1fac5f446a40cd864919d3929e4bf5ede..2ca705193cc8e5c77ba76f2b971935eaa23c73d7 100644
--- a/lib/private/updater.php
+++ b/lib/private/updater.php
@@ -105,6 +105,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 920161949ae417752a013ed20a157cc910e47704..75e1711b0de602d73b50b58792e30b48517abe06 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
 		);