diff --git a/core/Filechecks.php b/core/Filechecks.php
index ee29adad7e0516481bda951f80fed9aee0f8573c..387fa244ca6f82afb7df695f4264d68ed119e9bd 100644
--- a/core/Filechecks.php
+++ b/core/Filechecks.php
@@ -9,6 +9,8 @@
 namespace Piwik;
 
 use Piwik\Exception\MissingFilePermissionException;
+use Piwik\Plugins\CustomPiwikJs\Exception\AccessDeniedException;
+use Piwik\Plugins\CustomPiwikJs\TrackerUpdater;
 
 class Filechecks
 {
@@ -102,6 +104,40 @@ class Filechecks
         throw $ex;
     }
 
+    private static function isModifiedPathValid($path)
+    {
+        if ($path === 'piwik.js') {
+            // we could have used a postEvent hook to enrich "\Piwik\Manifest::$files;" which would also benefit plugins
+            // that want to check for file integrity but we do not want to risk to break anything right now. It is not
+            // as trivial because piwik.js might be already updated, or updated on the next request. We cannot define
+            // 2 or 3 different filesizes and md5 hashes for one file so we check it here.
+
+            if (Plugin\Manager::getInstance()->isPluginActivated('CustomPiwikJs')) {
+                $trackerUpdater = new TrackerUpdater();
+
+                if ($trackerUpdater->getCurrentTrackerFileContent() === $trackerUpdater->getUpdatedTrackerFileContent()) {
+                    // file was already updated, eg manually or via custom piwik.js, this is a valid piwik.js file as
+                    // it was enriched by tracker plugins
+                    return true;
+                }
+
+                try {
+                    // the piwik.js tracker file was not updated yet, but may be updated just after the update by
+                    // one of the events CustomPiwikJs is listening to or by a scheduled task.
+                    // In this case, we check whether such an update will succeed later and if it will, the file is
+                    // valid as well as it will be updated on the next request
+                    $trackerUpdater->checkWillSucceed();
+                    return true;
+                } catch (AccessDeniedException $e) {
+                    return false;
+                }
+
+            }
+        }
+
+        return false;
+    }
+
     /**
      * Get file integrity information (in PIWIK_INCLUDE_PATH).
      *
@@ -136,6 +172,11 @@ class Filechecks
             if (!file_exists($file) || !is_readable($file)) {
                 $messages[] = Piwik::translate('General_ExceptionMissingFile', $file);
             } elseif (filesize($file) != $props[0]) {
+
+                if (self::isModifiedPathValid($path)) {
+                    continue;
+                }
+
                 if (!$hasMd5 || in_array(substr($path, -4), array('.gif', '.ico', '.jpg', '.png', '.swf'))) {
                     // files that contain binary data (e.g., images) must match the file size
                     $messages[] = Piwik::translate('General_ExceptionFilesizeMismatch', array($file, $props[0], filesize($file)));
@@ -150,6 +191,10 @@ class Filechecks
                     }
                 }
             } elseif ($hasMd5file && (@md5_file($file) !== $props[1])) {
+                if (self::isModifiedPathValid($path)) {
+                    continue;
+                }
+
                 $messages[] = Piwik::translate('General_ExceptionFileIntegrity', $file);
             }
         }
diff --git a/plugins/CustomPiwikJs/TrackerUpdater.php b/plugins/CustomPiwikJs/TrackerUpdater.php
index 63702878826cd81567f8a72146ee8c4c6c233908..d90d8c166dbdd5f0112b64a450cf730ee9caf5b6 100644
--- a/plugins/CustomPiwikJs/TrackerUpdater.php
+++ b/plugins/CustomPiwikJs/TrackerUpdater.php
@@ -62,16 +62,28 @@ class TrackerUpdater
         $this->toFile->checkWritable();
     }
 
+    public function getCurrentTrackerFileContent()
+    {
+        return $this->toFile->getContent();
+    }
+
+    public function getUpdatedTrackerFileContent()
+    {
+        $trackingCode = new PiwikJsManipulator($this->fromFile->getContent(), $this->trackerFiles);
+        $newContent = $trackingCode->manipulateContent();
+
+        return $newContent;
+    }
+
     public function update()
     {
         if (!$this->toFile->hasWriteAccess() || !$this->fromFile->hasReadAccess()) {
             return;
         }
 
-        $trackingCode = new PiwikJsManipulator($this->fromFile->getContent(), $this->trackerFiles);
-        $newContent = $trackingCode->manipulateContent();
+        $newContent = $this->getUpdatedTrackerFileContent();
 
-        if ($newContent !== $this->toFile->getContent()) {
+        if ($newContent !== $this->getCurrentTrackerFileContent()) {
             $this->toFile->save($newContent);
         }
     }
diff --git a/plugins/CustomPiwikJs/tests/Integration/TrackerUpdaterTest.php b/plugins/CustomPiwikJs/tests/Integration/TrackerUpdaterTest.php
index 58650adf7e66e8a233e84dc49ed161a263162815..ef90785a5f2722be18b2eec8e99acb6e3d8dc5ed 100644
--- a/plugins/CustomPiwikJs/tests/Integration/TrackerUpdaterTest.php
+++ b/plugins/CustomPiwikJs/tests/Integration/TrackerUpdaterTest.php
@@ -74,6 +74,58 @@ class TrackerUpdaterTest extends IntegrationTestCase
         $updater->checkWillSucceed();
     }
 
+    public function test_getCurrentTrackerFileContent()
+    {
+        $targetFile = $this->dir . 'testpiwik.js';
+
+        $updater = $this->makeUpdater(null, $targetFile);
+        $content = $updater->getCurrentTrackerFileContent();
+
+        $this->assertSame(file_get_contents($targetFile), $content);
+    }
+
+    public function test_getUpdatedTrackerFileContent_returnsGeneratedPiwikJsWithMergedTrackerFiles_WhenTheyExist()
+    {
+        $source = $this->dir . 'testpiwik.js';
+        $target = $this->dir . 'MyTestTarget.js';
+
+        $updater = $this->makeUpdater($source, $target);
+        $updater->setTrackerFiles(new PluginTrackerFilesMock(array(
+            $this->dir . 'tracker.js', $this->dir . 'tracker.min.js'
+        )));
+        $content = $updater->getUpdatedTrackerFileContent();
+
+        $this->assertSame('/** MyHeader*/
+var PiwikJs = "mytest";
+
+/*!!! pluginTrackerHook */
+
+/* GENERATED: tracker.min.js */
+
+/* END GENERATED: tracker.min.js */
+
+
+/* GENERATED: tracker.js */
+
+/* END GENERATED: tracker.js */
+
+
+var myArray = [];
+', $content);
+    }
+
+    public function test_getUpdatedTrackerFileContent_returnsSourceFile_IfNoTrackerFilesFound()
+    {
+        $source = $this->dir . 'testpiwik.js';
+        $target = $this->dir . 'MyTestTarget.js';
+
+        $updater = $this->makeUpdater($source, $target);
+        $updater->setTrackerFiles(new PluginTrackerFilesMock(array()));
+        $content = $updater->getUpdatedTrackerFileContent();
+
+        $this->assertSame(file_get_contents($source), $content);
+    }
+
     public function test_update_shouldNotThrowAnError_IfTargetFileIsNotWritable()
     {
         $updater = $this->makeUpdater(null, $this->dir . 'MyNotExisIngFilessss.js');