diff --git a/lib/private/api.php b/lib/private/api.php
index 748876909520285c35e8f82443c2ff4dd6374c88..e9c144564f0a684e5efa0bfb3f06e022a2515f4c 100644
--- a/lib/private/api.php
+++ b/lib/private/api.php
@@ -301,7 +301,7 @@ class OC_API {
 	 * @param OC_OCS_Result $result
 	 * @param string $format the format xml|json
 	 */
-	private static function respond($result, $format='xml') {
+	public static function respond($result, $format='xml') {
 		// Send 401 headers if unauthorised
 		if($result->getStatusCode() === self::RESPOND_UNAUTHORISED) {
 			header('WWW-Authenticate: Basic realm="Authorisation Required"');
diff --git a/ocs/v1.php b/ocs/v1.php
index d69904fc4954c8f898f1e945e2d3d1d97c297d93..0a86fb064117c2d45fe6c492714c3dd27d1ae46f 100644
--- a/ocs/v1.php
+++ b/ocs/v1.php
@@ -23,6 +23,15 @@
 
 require_once '../lib/base.php';
 
+if (\OCP\Util::needUpgrade()) {
+	// since the behavior of apps or remotes are unpredictable during
+	// an upgrade, return a 503 directly
+	OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
+	$response = new OC_OCS_Result(null, OC_Response::STATUS_SERVICE_UNAVAILABLE, 'Service unavailable');
+	OC_API::respond($response, OC_API::requestedFormat());
+	exit;
+}
+
 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
 use Symfony\Component\Routing\Exception\MethodNotAllowedException;
 
diff --git a/public.php b/public.php
index eed63948112831bb57349da8117f0086edb71470..1f858fd073d6f684dd7bc62415757d2f74b5f8ff 100644
--- a/public.php
+++ b/public.php
@@ -3,6 +3,14 @@
 try {
 
 	require_once 'lib/base.php';
+	if (\OCP\Util::needUpgrade()) {
+		// since the behavior of apps or remotes are unpredictable during
+		// an upgrade, return a 503 directly
+		OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
+		OC_Template::printErrorPage('Service unavailable');
+		exit;
+	}
+
 	OC::checkMaintenanceMode();
 	OC::checkSingleUserMode();
 	$pathInfo = OC_Request::getPathInfo();