diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
index 37a0b4c921854019ab8d660bcc6ec13378a1804d..d2d3a902f0e687b10ebbab2956794afed0ef829a 100644
--- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
@@ -607,6 +607,9 @@ void BuildDirManager::maybeForceReparse()
     const QByteArray EXTRA_GENERATOR_KEY = "CMAKE_EXTRA_GENERATOR";
     const QByteArray CMAKE_COMMAND_KEY = "CMAKE_COMMAND";
 
+    const QByteArrayList criticalKeys
+            = QByteArrayList() << GENERATOR_KEY << EXTRA_GENERATOR_KEY << CMAKE_COMMAND_KEY;
+
     if (!m_hasData) {
         forceReparse();
         return;
@@ -614,6 +617,8 @@ void BuildDirManager::maybeForceReparse()
 
     const CMakeConfig currentConfig = parsedConfiguration();
 
+    const CMakeTool *tool = CMakeKitInformation::cmakeTool(kit());
+    QTC_ASSERT(tool, return); // No cmake... we should not have ended up here in the first place
     const QString kitGenerator = CMakeGeneratorKitInformation::generator(kit());
     int pos = kitGenerator.lastIndexOf(QLatin1String(" - "));
     const QString extraKitGenerator = (pos > 0) ? kitGenerator.left(pos) : QString();
@@ -623,37 +628,42 @@ void BuildDirManager::maybeForceReparse()
                                      QByteArray(), mainKitGenerator.toUtf8()));
     if (!extraKitGenerator.isEmpty())
         targetConfig.append(CMakeConfigItem(EXTRA_GENERATOR_KEY, CMakeConfigItem::INTERNAL,
-                                         QByteArray(), extraKitGenerator.toUtf8()));
-    const CMakeTool *tool = CMakeKitInformation::cmakeTool(kit());
-    if (tool)
-        targetConfig.append(CMakeConfigItem(CMAKE_COMMAND_KEY, CMakeConfigItem::INTERNAL,
-                                         QByteArray(), tool->cmakeExecutable().toUserOutput().toUtf8()));
+                                            QByteArray(), extraKitGenerator.toUtf8()));
+    targetConfig.append(CMakeConfigItem(CMAKE_COMMAND_KEY, CMakeConfigItem::INTERNAL,
+                                        QByteArray(), tool->cmakeExecutable().toUserOutput().toUtf8()));
     Utils::sort(targetConfig, CMakeConfigItem::sortOperator());
 
+    bool mustReparse = false;
     auto ccit = currentConfig.constBegin();
     auto kcit = targetConfig.constBegin();
+
     while (ccit != currentConfig.constEnd() && kcit != targetConfig.constEnd()) {
         if (ccit->key == kcit->key) {
-            if (ccit->value != kcit->value)
-                break;
+            if (ccit->value != kcit->value) {
+                if (criticalKeys.contains(kcit->key)) {
+                        clearCache();
+                        return;
+                }
+                mustReparse = true;
+            }
             ++ccit;
             ++kcit;
         } else {
-            if (ccit->key < kcit->key)
+            if (ccit->key < kcit->key) {
                 ++ccit;
-            else
-                break;
+            } else {
+                ++kcit;
+                mustReparse = true;
+            }
         }
     }
 
-    if (kcit != targetConfig.end()) {
-        if (kcit->key == GENERATOR_KEY
-                || kcit->key == EXTRA_GENERATOR_KEY
-                || kcit->key == CMAKE_COMMAND_KEY)
-            clearCache();
-        else
-            forceReparse();
-    }
+    // If we have keys that do not exist yet, then reparse.
+    //
+    // The critical keys *must* be set in cmake configuration, so those were already
+    // handled above.
+    if (mustReparse || kcit != targetConfig.constEnd())
+        forceReparse();
 }
 
 } // namespace Internal