diff --git a/application/controllers/DashboardController.php b/application/controllers/DashboardController.php
index e9aac4a95..ff2580c1b 100644
--- a/application/controllers/DashboardController.php
+++ b/application/controllers/DashboardController.php
@@ -106,29 +106,22 @@ class DashboardController extends ActionController
         $action = $this;
         $form->setOnSuccess(function (Form $form) use ($dashboard, $action) {
             try {
-                $pane = $dashboard->getPane($form->getValue('pane'));
+                $pane = $dashboard->getPane($form->getValue('org_pane'));
+                $pane->setTitle($form->getValue('pane'));
             } catch (ProgrammingError $e) {
                 $pane = new Dashboard\Pane($form->getValue('pane'));
                 $pane->setUserWidget();
                 $dashboard->addPane($pane);
             }
             try {
-                $dashlet = $pane->getDashlet($form->getValue('dashlet'));
+                $dashlet = $pane->getDashlet($form->getValue('org_dashlet'));
+                $dashlet->setTitle($form->getValue('dashlet'));
                 $dashlet->setUrl($form->getValue('url'));
             } catch (ProgrammingError $e) {
                 $dashlet = new Dashboard\Dashlet($form->getValue('dashlet'), $form->getValue('url'), $pane);
                 $pane->addDashlet($dashlet);
             }
             $dashlet->setUserWidget();
-            // Rename dashlet
-            if ($form->getValue('org_dashlet') && $form->getValue('org_dashlet') !== $dashlet->getTitle()) {
-                $pane->removeDashlet($form->getValue('org_dashlet'));
-            }
-            // Move
-            if ($form->getValue('org_pane') && $form->getValue('org_pane') !== $pane->getTitle()) {
-                $oldPane = $dashboard->getPane($form->getValue('org_pane'));
-                $oldPane->removeDashlet($dashlet->getTitle());
-            }
             $dashboardConfig = $dashboard->getConfig();
             try {
                 $dashboardConfig->saveIni();
@@ -269,7 +262,7 @@ class DashboardController extends ActionController
         $action = $this;
         $form->setOnSuccess(function (Form $form) use ($dashboard, $pane, $action) {
             $pane = $dashboard->getPane($pane);
-            $dashboard->removePane($pane->getTitle());
+            $dashboard->removePane($pane->getName());
             $dashboardConfig = $dashboard->getConfig();
             try {
                 $dashboardConfig->saveIni();
diff --git a/application/forms/Dashboard/DashletForm.php b/application/forms/Dashboard/DashletForm.php
index 22f1f6c5a..1af65a954 100644
--- a/application/forms/Dashboard/DashletForm.php
+++ b/application/forms/Dashboard/DashletForm.php
@@ -161,10 +161,10 @@ class DashletForm extends Form
     public function load(Dashlet $dashlet)
     {
         $this->populate(array(
-            'pane'          => $dashlet->getPane()->getName(),
+            'pane'          => $dashlet->getPane()->getTitle(),
             'org_pane'      => $dashlet->getPane()->getName(),
             'dashlet'       => $dashlet->getTitle(),
-            'org_dashlet'   => $dashlet->getTitle(),
+            'org_dashlet'   => $dashlet->getName(),
             'url'           => $dashlet->getUrl()->getRelativeUrl()
         ));
     }
diff --git a/application/views/scripts/dashboard/settings.phtml b/application/views/scripts/dashboard/settings.phtml
index ffa48b78a..ba672988e 100644
--- a/application/views/scripts/dashboard/settings.phtml
+++ b/application/views/scripts/dashboard/settings.phtml
@@ -59,7 +59,7 @@
                                 <?= $this->qlink(
                                     $dashlet->getTitle(),
                                     'dashboard/update-dashlet',
-                                    array('pane' => $pane->getName(), 'dashlet' => $dashlet->getTitle()),
+                                    array('pane' => $pane->getName(), 'dashlet' => $dashlet->getName()),
                                     array('title' => sprintf($this->translate('Edit dashlet %s'), $dashlet->getTitle()))
                                 ); ?>
                             </td>
@@ -75,10 +75,10 @@
                                 <?= $this->qlink(
                                     '',
                                     'dashboard/remove-dashlet',
-                                    array('pane' => $pane->getName(), 'dashlet' => $dashlet->getTitle()),
+                                    array('pane' => $pane->getName(), 'dashlet' => $dashlet->getName()),
                                     array(
                                         'icon'  => 'trash',
-                                        'title' => sprintf($this->translate('Remove dashlet %s from pane %s'), $dashlet->getTitle(), $pane->getName())
+                                        'title' => sprintf($this->translate('Remove dashlet %s from pane %s'), $dashlet->getTitle(), $pane->getTitle())
                                     )
                                 ); ?>
                             </td>
diff --git a/doc/80-Upgrading.md b/doc/80-Upgrading.md
index ddc8f146b..e621a7439 100644
--- a/doc/80-Upgrading.md
+++ b/doc/80-Upgrading.md
@@ -14,6 +14,9 @@ v2.3 to v2.5 requires to follow the instructions for v2.4 too.
   for log messages emitted by jquery-migrate. (https://github.com/jquery/jquery-migrate) Your javascript code will still
   work, though jquery-migrate will notify you if you're utilizing deprecated/removed functions. jquery-migrate will be
   removed with Icinga Web v2.8 and code not adjusted accordingly will stop working.
+* If you're using a language other than english and you've adjusted or disabled module dashboards, you'll need to
+  update all of your `dashboard.ini` files. A CLI command exists to assist you with this task. Enable the `migrate`
+  module and run the following on the host where these files exist: `icingacli migrate dashboard sections --verbose`
 
 ## Upgrading to Icinga Web 2 2.6.x <a id="upgrading-to-2.6.x"></a>
 
diff --git a/library/Icinga/Application/Modules/Module.php b/library/Icinga/Application/Modules/Module.php
index 450de7ded..735738089 100644
--- a/library/Icinga/Application/Modules/Module.php
+++ b/library/Icinga/Application/Modules/Module.php
@@ -314,9 +314,12 @@ class Module
         $navigation = new Navigation();
         foreach ($panes as $pane) {
             /** @var DashboardContainer $pane */
-            $dashlets = array();
+            $dashlets = [];
             foreach ($pane->getDashlets() as $dashletName => $dashletUrl) {
-                $dashlets[$this->translate($dashletName)] = $dashletUrl;
+                $dashlets[$dashletName] = [
+                    'label' => $this->translate($dashletName),
+                    'url'   => $dashletUrl
+                ];
             }
 
             $navigation->addItem(
@@ -326,7 +329,7 @@ class Module
                     array(
                         'label'     => $this->translate($pane->getName()),
                         'type'      => 'dashboard-pane',
-                        'dashlets'  => $dashlets
+                        'children'  => $dashlets
                     )
                 )
             );
diff --git a/library/Icinga/Legacy/DashboardConfig.php b/library/Icinga/Legacy/DashboardConfig.php
index 54cd3b78f..3fb5c2fc2 100644
--- a/library/Icinga/Legacy/DashboardConfig.php
+++ b/library/Icinga/Legacy/DashboardConfig.php
@@ -5,6 +5,9 @@ namespace Icinga\Legacy;
 
 use Icinga\Application\Config;
 use Icinga\User;
+use Icinga\Web\Navigation\DashboardPane;
+use Icinga\Web\Navigation\Navigation;
+use Icinga\Web\Navigation\NavigationItem;
 
 /**
  * Legacy dashboard config class for case insensitive interpretation of dashboard config files
@@ -76,6 +79,51 @@ class DashboardConfig extends Config
      */
     public function saveIni($filePath = null, $fileMode = 0660)
     {
+        // Preprocessing start, ensures that the non-translated names are used to save module dashboard changes
+        // TODO: This MUST NOT survive the new dashboard implementation (yes, it's still a thing..)
+        $dashboardNavigation = new Navigation();
+        $dashboardNavigation->load('dashboard-pane');
+        $getDashboardPane = function ($label) use ($dashboardNavigation) {
+            foreach ($dashboardNavigation as $dashboardPane) {
+                /** @var DashboardPane $dashboardPane */
+                if ($dashboardPane->getLabel() === $label) {
+                    return $dashboardPane;
+                }
+
+                foreach ($dashboardPane->getChildren() as $dashlet) {
+                    /** @var NavigationItem $dashlet */
+                    if ($dashlet->getLabel() === $label) {
+                        return $dashlet;
+                    }
+                }
+            }
+        };
+
+        foreach (clone $this->config as $name => $options) {
+            if (strpos($name, '.') !== false) {
+                list($dashboardLabel, $dashletLabel) = explode('.', $name, 2);
+            } else {
+                $dashboardLabel = $name;
+                $dashletLabel = null;
+            }
+
+            $dashboardPane = $getDashboardPane($dashboardLabel);
+            if ($dashboardPane !== null) {
+                $dashboardLabel = $dashboardPane->getName();
+            }
+
+            if ($dashletLabel !== null) {
+                $dashletItem = $getDashboardPane($dashletLabel);
+                if ($dashletItem !== null) {
+                    $dashletLabel = $dashletItem->getName();
+                }
+            }
+
+            unset($this->config[$name]);
+            $this->config[$dashboardLabel . ($dashletLabel ? '.' . $dashletLabel : '')] = $options;
+        }
+        // Preprocessing end
+
         parent::saveIni($filePath, $fileMode);
         if ($filePath === null) {
             $filePath = $this->configFile;
diff --git a/library/Icinga/Web/Navigation/DashboardPane.php b/library/Icinga/Web/Navigation/DashboardPane.php
index f87259b03..71b3215cf 100644
--- a/library/Icinga/Web/Navigation/DashboardPane.php
+++ b/library/Icinga/Web/Navigation/DashboardPane.php
@@ -62,19 +62,6 @@ class DashboardPane extends NavigationItem
         $this->setUrl(Url::fromPath('dashboard', array('pane' => $this->getName())));
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    public function merge(NavigationItem $item)
-    {
-        parent::merge($item);
-
-        $this->setDashlets(array_merge(
-            $this->getDashlets(false),
-            $item->getDashlets(false)
-        ));
-    }
-
     /**
      * Set disabled state for pane
      *
diff --git a/library/Icinga/Web/Widget/Dashboard.php b/library/Icinga/Web/Widget/Dashboard.php
index 83b0be654..5a8796d27 100644
--- a/library/Icinga/Web/Widget/Dashboard.php
+++ b/library/Icinga/Web/Widget/Dashboard.php
@@ -77,15 +77,15 @@ class Dashboard extends AbstractWidget
         foreach ($navigation as $dashboardPane) {
             /** @var DashboardPane $dashboardPane */
             $pane = new Pane($dashboardPane->getLabel());
-            foreach ($dashboardPane->getDashlets(false) as $title => $url) {
-                $pane->addDashlet($title, $url);
+            foreach ($dashboardPane->getChildren() as $dashlet) {
+                $pane->addDashlet($dashlet->getLabel(), $dashlet->getUrl());
             }
 
             $panes[] = $pane;
         }
 
         $this->mergePanes($panes);
-        $this->loadUserDashboards();
+        $this->loadUserDashboards($navigation);
         return $this;
     }
 
@@ -103,7 +103,7 @@ class Dashboard extends AbstractWidget
             }
             foreach ($pane->getDashlets() as $dashlet) {
                 if ($dashlet->isUserWidget()) {
-                    $output[$pane->getName() . '.' . $dashlet->getTitle()] = $dashlet->toArray();
+                    $output[$pane->getName() . '.' . $dashlet->getName()] = $dashlet->toArray();
                 }
             }
         }
@@ -114,10 +114,10 @@ class Dashboard extends AbstractWidget
     /**
      * Load user dashboards from all config files that match the username
      */
-    protected function loadUserDashboards()
+    protected function loadUserDashboards(Navigation $navigation)
     {
         foreach (DashboardConfig::listConfigFilesForUser($this->user) as $file) {
-            $this->loadUserDashboardsFromFile($file);
+            $this->loadUserDashboardsFromFile($file, $navigation);
         }
     }
 
@@ -128,7 +128,7 @@ class Dashboard extends AbstractWidget
      *
      * @return  bool
      */
-    protected function loadUserDashboardsFromFile($file)
+    protected function loadUserDashboardsFromFile($file, Navigation $dashboardNavigation)
     {
         try {
             $config = Config::fromIni($file);
@@ -143,8 +143,12 @@ class Dashboard extends AbstractWidget
         $dashlets = array();
         foreach ($config as $key => $part) {
             if (strpos($key, '.') === false) {
-                if ($this->hasPane($part->title)) {
-                    $panes[$key] = $this->getPane($part->title);
+                $dashboardPane = $dashboardNavigation->getItem($key);
+                if ($dashboardPane !== null) {
+                    $key = $dashboardPane->getLabel();
+                }
+                if ($this->hasPane($key)) {
+                    $panes[$key] = $this->getPane($key);
                 } else {
                     $panes[$key] = new Pane($key);
                     $panes[$key]->setTitle($part->title);
@@ -155,6 +159,14 @@ class Dashboard extends AbstractWidget
                 }
             } else {
                 list($paneName, $dashletName) = explode('.', $key, 2);
+                $dashboardPane = $dashboardNavigation->getItem($paneName);
+                if ($dashboardPane !== null) {
+                    $paneName = $dashboardPane->getLabel();
+                    $dashletItem = $dashboardPane->getChildren()->getItem($dashletName);
+                    if ($dashletItem !== null) {
+                        $dashletName = $dashletItem->getLabel();
+                    }
+                }
                 $part->pane = $paneName;
                 $part->dashlet = $dashletName;
                 $dashlets[] = $part;
@@ -175,6 +187,7 @@ class Dashboard extends AbstractWidget
                 $dashletData->url,
                 $pane
             );
+            $dashlet->setName($dashletData->dashlet);
 
             if ((bool) $dashletData->get('disabled', false) === true) {
                 $dashlet->setDisabled(true);
@@ -200,7 +213,7 @@ class Dashboard extends AbstractWidget
     {
         /** @var $pane Pane  */
         foreach ($panes as $pane) {
-            if ($this->hasPane($pane->getTitle()) === true) {
+            if ($this->hasPane($pane->getName()) === true) {
                 /** @var $current Pane */
                 $current = $this->panes[$pane->getName()];
                 $current->addDashlets($pane->getDashlets());
diff --git a/library/Icinga/Web/Widget/Dashboard/Dashlet.php b/library/Icinga/Web/Widget/Dashboard/Dashlet.php
index 17f971f0a..b9b2eb0d1 100644
--- a/library/Icinga/Web/Widget/Dashboard/Dashlet.php
+++ b/library/Icinga/Web/Widget/Dashboard/Dashlet.php
@@ -22,6 +22,8 @@ class Dashlet extends UserWidget
      */
     private $url;
 
+    private $name;
+
     /**
      * The title being displayed on top of the dashlet
      * @var
@@ -91,11 +93,23 @@ EOD;
      */
     public function __construct($title, $url, Pane $pane)
     {
+        $this->name = $title;
         $this->title = $title;
         $this->pane = $pane;
         $this->url = $url;
     }
 
+    public function setName($name)
+    {
+        $this->name = $name;
+        return $this;
+    }
+
+    public function getName()
+    {
+        return $this->name;
+    }
+
     /**
      * Retrieve the dashlets title
      *
diff --git a/library/Icinga/Web/Widget/Dashboard/Pane.php b/library/Icinga/Web/Widget/Dashboard/Pane.php
index 967ba48e9..c8b14c5a1 100644
--- a/library/Icinga/Web/Widget/Dashboard/Pane.php
+++ b/library/Icinga/Web/Widget/Dashboard/Pane.php
@@ -22,7 +22,6 @@ class Pane extends UserWidget
 
     /**
      * The title of this pane, as displayed in the dashboard tabs
-     * @TODO: Currently the same as $name, evaluate if distinguishing is needed
      *
      * @var string
      */
@@ -229,7 +228,7 @@ class Pane extends UserWidget
     public function addDashlet($dashlet, $url = null)
     {
         if ($dashlet instanceof Dashlet) {
-            $this->dashlets[$dashlet->getTitle()] = $dashlet;
+            $this->dashlets[$dashlet->getName()] = $dashlet;
         } elseif (is_string($dashlet) && $url !== null) {
              $this->createDashlet($dashlet, $url);
         } else {
@@ -248,15 +247,15 @@ class Pane extends UserWidget
     {
         /* @var $dashlet Dashlet */
         foreach ($dashlets as $dashlet) {
-            if (array_key_exists($dashlet->getTitle(), $this->dashlets)) {
-                if (preg_match('/_(\d+)$/', $dashlet->getTitle(), $m)) {
-                    $name = preg_replace('/_\d+$/', $m[1]++, $dashlet->getTitle());
+            if (array_key_exists($dashlet->getName(), $this->dashlets)) {
+                if (preg_match('/_(\d+)$/', $dashlet->getName(), $m)) {
+                    $name = preg_replace('/_\d+$/', $m[1]++, $dashlet->getName());
                 } else {
-                    $name = $dashlet->getTitle() . '_2';
+                    $name = $dashlet->getName() . '_2';
                 }
                 $this->dashlets[$name] = $dashlet;
             } else {
-                $this->dashlets[$dashlet->getTitle()] = $dashlet;
+                $this->dashlets[$dashlet->getName()] = $dashlet;
             }
         }
 
diff --git a/modules/migrate/application/clicommands/DashboardCommand.php b/modules/migrate/application/clicommands/DashboardCommand.php
new file mode 100644
index 000000000..4cb89a003
--- /dev/null
+++ b/modules/migrate/application/clicommands/DashboardCommand.php
@@ -0,0 +1,122 @@
+<?php
+/* Icinga Web 2 | (c) 2019 Icinga GmbH | GPLv2+ */
+
+namespace Icinga\Module\Migrate\Clicommands;
+
+use Exception;
+use Icinga\Application\Config;
+use Icinga\Application\Icinga;
+use Icinga\Application\Modules\DashboardContainer;
+use Icinga\Cli\Command;
+use Icinga\Application\Logger;
+use Icinga\Util\Translator;
+use ReflectionClass;
+
+class DashboardCommand extends Command
+{
+    /**
+     * Rename translated dashboard sections
+     *
+     * Migrates all locally found dashboard configurations so that the effects of
+     * https://github.com/Icinga/icingaweb2/issues/3542 are reversed.
+     *
+     * USAGE
+     *
+     *  icingacli migrate dashboard sections
+     */
+    public function sectionsAction()
+    {
+        $moduleReflection = new ReflectionClass('Icinga\Application\Modules\Module');
+        // There's no direct way to invoke this method
+        $launchConfigScriptMethod = $moduleReflection->getMethod('launchConfigScript');
+        $launchConfigScriptMethod->setAccessible(true);
+        // Calling getDashboard() results in Url::fromPath() getting called as well == the CLI's death
+        $paneItemsProperty = $moduleReflection->getProperty('paneItems');
+        $paneItemsProperty->setAccessible(true);
+        // Again, no direct way to access this nor to let the module setup its own translation domain
+        $localeDirProperty = $moduleReflection->getProperty('localedir');
+        $localeDirProperty->setAccessible(true);
+
+        $locales = Translator::getAvailableLocaleCodes();
+        $modules = Icinga::app()->getModuleManager()->loadEnabledModules()->getLoadedModules();
+        foreach ($this->listDashboardConfigs() as $path) {
+            Logger::info('Migrating dashboard config: %s', $path);
+
+            $config = Config::fromIni($path);
+            foreach ($modules as $module) {
+                $localePath = $localeDirProperty->getValue($module);
+                if (! is_dir($localePath)) {
+                    // Modules without any translations are not affected
+                    continue;
+                }
+
+                $launchConfigScriptMethod->invoke($module);
+                Translator::registerDomain($module->getName(), $localePath);
+
+                foreach ($locales as $locale) {
+                    if ($locale === 'en_US') {
+                        continue;
+                    }
+
+                    Translator::setupLocale($locale);
+
+                    foreach ($paneItemsProperty->getValue($module) as $paneName => $container) {
+                        /** @var DashboardContainer $container */
+                        foreach ($config->toArray() as $section => $options) {
+                            if (strpos($section, '.') !== false) {
+                                list($paneTitle, $dashletTitle) = explode('.', $section, 2);
+                            } else {
+                                $paneTitle = $section;
+                                $dashletTitle = null;
+                            }
+
+                            if (isset($options['disabled']) && mt($module->getName(), $paneName) !== $paneTitle) {
+                                // `disabled` is checked because if it's a module's pane that's the only reason
+                                // why it's in there. If a user utilized the same label though for a custom pane,
+                                // it remains as is.
+                                continue;
+                            }
+
+                            $dashletName = null;
+                            if ($dashletTitle !== null) {
+                                foreach ($container->getDashlets() as $name => $url) {
+                                    if (mt($module->getName(), $name) === $dashletTitle) {
+                                        $dashletName = $name;
+                                        break;
+                                    }
+                                }
+                            }
+
+                            $newSection = $paneName . ($dashletName ? '.' . $dashletName : '');
+                            $config->removeSection($section);
+                            $config->setSection($newSection, $options);
+
+                            Logger::info('Migrated section "%s" to "%s"', $section, $newSection);
+                        }
+                    }
+                }
+            }
+
+            $config->saveIni();
+        }
+    }
+
+    protected function listDashboardConfigs()
+    {
+        $dashboardConfigPath = Config::resolvePath('dashboards');
+
+        try {
+            $dashboardConfigDir = opendir($dashboardConfigPath);
+        } catch (Exception $e) {
+            Logger::error('Cannot access dashboard configuration: %s', $e);
+            exit(1);
+        }
+
+        while ($entry = readdir($dashboardConfigDir)) {
+            $userDashboardPath = join(DIRECTORY_SEPARATOR, [$dashboardConfigPath, $entry, 'dashboard.ini']);
+            if (is_file($userDashboardPath)) {
+                yield $userDashboardPath;
+            }
+        }
+    }
+}