diff --git a/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php b/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php
index 33784b29b745b247ccf962d125a809c4e3edd2cf..ba5a597a230bc1c9366825eee26c06d50f64c897 100644
--- a/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php
+++ b/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php
@@ -130,9 +130,31 @@ class DataMapProcessor
             $this->enrich($this->nextItems);
         }
 
+        $this->allDataMap = $this->purgeDataMap($this->allDataMap);
         return $this->allDataMap;
     }
 
+    /**
+     * Purges superfluous empty data-map sections.
+     *
+     * @param array $dataMap
+     * @return array
+     */
+    protected function purgeDataMap(array $dataMap): array
+    {
+        foreach ($dataMap as $tableName => $idValues) {
+            foreach ($idValues as $id => $values) {
+                if (empty($values)) {
+                    unset($dataMap[$tableName][$id]);
+                }
+            }
+            if (empty($dataMap[$tableName])) {
+                unset($dataMap[$tableName]);
+            }
+        }
+        return $dataMap;
+    }
+
     /**
      * Create data map items of all affected rows
      *
@@ -203,7 +225,7 @@ class DataMapProcessor
     }
 
     /**
-     * Sanitizes the submitted data-map and removes fields which are not
+     * Sanitizes the submitted data-map items and removes fields which are not
      * defined as custom and thus rely on either parent or source values.
      *
      * @param DataMapItem[] $items
@@ -253,7 +275,7 @@ class DataMapProcessor
         foreach ($item->getApplicableScopes() as $scope) {
             $fieldNames = array_merge(
                 $fieldNames,
-                $this->getFieldNamesForItemScope($item, $scope, !$item->isNew())
+                $this->getFieldNamesForItemScope($item, $scope, false)
             );
         }
 
@@ -669,7 +691,7 @@ class DataMapProcessor
             $suggestedAncestorIds = $this->mapRelationItemId($relationHandler->itemArray);
         }
 
-        return $suggestedAncestorIds;
+        return array_filter($suggestedAncestorIds);
     }
 
     /**
@@ -701,7 +723,7 @@ class DataMapProcessor
             $persistedIds = $this->mapRelationItemId($relationHandler->itemArray);
         }
 
-        return $persistedIds;
+        return array_filter($persistedIds);
     }
 
     /**
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/AbstractActionTestCase.php b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/AbstractActionTestCase.php
index c4599ca0bea1d33a64a346b752f5900fee7a4604..9c26360ffc9e4ac2b366d89a55bcf20f9758a7fa 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/AbstractActionTestCase.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/AbstractActionTestCase.php
@@ -29,6 +29,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
     const VALUE_HotelIdFirst = 3;
     const VALUE_HotelIdSecond = 4;
     const VALUE_HotelIdThird = 5;
+    const VALUE_OfferIdLast = 8;
     const VALUE_LanguageId = 1;
     const VALUE_LanguageIdSecond = 2;
 
@@ -200,6 +201,48 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         $this->recordIds['newPriceId'] = $this->actionService->getDataHandler()->substNEWwithIDs[$newPriceId];
     }
 
+    /**
+     * @see DataSet/localizeParentContentSynchronization.csv
+     */
+    public function localizeParentContentAndSetInvalidChildReferenceWithLanguageSynchronization()
+    {
+        $GLOBALS['TCA'][self::TABLE_Content]['columns'][self::FIELD_ContentHotel]['config']['behaviour']['allowLanguageSynchronization'] = true;
+        $GLOBALS['TCA'][self::TABLE_Hotel]['columns'][self::FIELD_HotelOffer]['config']['behaviour']['allowLanguageSynchronization'] = true;
+        $GLOBALS['TCA'][self::TABLE_Offer]['columns'][self::FIELD_OfferPrice]['config']['behaviour']['allowLanguageSynchronization'] = true;
+        $newTableIds = $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
+        $this->recordIds['localizedContentId'] = $newTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
+        // modify IRRE relation value of localized record (which should be sanitized and filtered)
+        $this->actionService->modifyRecord(self::TABLE_Content, $this->recordIds['localizedContentId'], [self::FIELD_ContentHotel => '0']);
+    }
+
+    /**
+     * @see DataSet/localizeParentContentSynchronization.csv
+     */
+    public function localizeParentContentAndSetInvalidChildReferenceWithLateLanguageSynchronization()
+    {
+        // disable language synchronization
+        $GLOBALS['TCA'][self::TABLE_Content]['columns'][self::FIELD_ContentHotel]['config']['behaviour']['allowLanguageSynchronization'] = false;
+        $GLOBALS['TCA'][self::TABLE_Hotel]['columns'][self::FIELD_HotelOffer]['config']['behaviour']['allowLanguageSynchronization'] = false;
+        $GLOBALS['TCA'][self::TABLE_Offer]['columns'][self::FIELD_OfferPrice]['config']['behaviour']['allowLanguageSynchronization'] = false;
+        $newTableIds = $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
+        $this->recordIds['localizedContentId'] = $newTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
+        $this->recordIds['localizedHotelId'] = $newTableIds[self::TABLE_Hotel][self::VALUE_HotelIdThird];
+        $this->recordIds['localizedOfferId'] = $newTableIds[self::TABLE_Offer][self::VALUE_OfferIdLast];
+        // now enable language synchronization
+        $GLOBALS['TCA'][self::TABLE_Content]['columns'][self::FIELD_ContentHotel]['config']['behaviour']['allowLanguageSynchronization'] = true;
+        $GLOBALS['TCA'][self::TABLE_Hotel]['columns'][self::FIELD_HotelOffer]['config']['behaviour']['allowLanguageSynchronization'] = true;
+        $GLOBALS['TCA'][self::TABLE_Offer]['columns'][self::FIELD_OfferPrice]['config']['behaviour']['allowLanguageSynchronization'] = true;
+        // modify IRRE relation values of localized records (which should be sanitized and filtered)
+        $this->actionService->modifyRecords(
+            self::VALUE_PageId,
+            [
+                self::TABLE_Content => ['uid' => $this->recordIds['localizedContentId'], self::FIELD_ContentHotel => '0'],
+                self::TABLE_Hotel => ['uid' => $this->recordIds['localizedHotelId'], self::FIELD_ContentHotel => '0'],
+                self::TABLE_Offer => ['uid' => $this->recordIds['localizedOfferId'], self::FIELD_ContentHotel => '0'],
+            ]
+        );
+    }
+
     /**
      * @see DataSet/changeParentContentRecordSorting.csv
      */
@@ -506,7 +549,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         $this->actionService->modifyRecords(
             $this->recordIds['localizedPageId'],
             [
-                self::TABLE_Page => ['uid' => $this->recordIds['localizedPageId'], self::FIELD_PageHotel => '6,__nextUid'],
+                self::TABLE_Page => ['uid' => $this->recordIds['localizedPageId'], self::FIELD_PageHotel => '6,__nextUid', 'l10n_state' => [self::FIELD_PageHotel => 'custom']],
                 self::TABLE_Hotel => ['uid' => '__NEW', 'sys_language_uid' => self::VALUE_LanguageId, 'title' => 'Hotel in dansk page only'],
             ]
         );
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php
index 626e87e2d7d512a589728213f26eab5b0566458f..8e1ab4e53d71922ce91237c6fb50cae47d5f29b5 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php
@@ -183,6 +183,38 @@ class ActionTest extends \TYPO3\CMS\Core\Tests\Functional\DataHandling\IRRE\Fore
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1', '[Translate to Dansk:] New Hotel #1'));
     }
 
+    /**
+     * @test
+     * @see DataSet/localizeParentContentSynchronization.csv
+     */
+    public function localizeParentContentAndSetInvalidChildReferenceWithLanguageSynchronization()
+    {
+        parent::localizeParentContentAndSetInvalidChildReferenceWithLanguageSynchronization();
+        // the assertion is the same as for localizeParentContentWithLanguageSynchronization()
+        $this->assertAssertionDataSet('localizeParentContentSynchronization');
+
+        $responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseSections('Default', 'Extbase:list()');
+        $this->assertThat($responseSections, $this->getRequestSectionStructureHasRecordConstraint()
+            ->setRecordIdentifier(self::TABLE_Content . ':' . self::VALUE_ContentIdLast)->setRecordField(self::FIELD_ContentHotel)
+            ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
+    }
+
+    /**
+     * @test
+     * @see DataSet/localizeParentContentSynchronization.csv
+     */
+    public function localizeParentContentAndSetInvalidChildReferenceWithLateLanguageSynchronization()
+    {
+        parent::localizeParentContentAndSetInvalidChildReferenceWithLateLanguageSynchronization();
+        // the assertion is the same as for localizeParentContentWithLanguageSynchronization()
+        $this->assertAssertionDataSet('localizeParentContentSynchronization');
+
+        $responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseSections('Default', 'Extbase:list()');
+        $this->assertThat($responseSections, $this->getRequestSectionStructureHasRecordConstraint()
+            ->setRecordIdentifier(self::TABLE_Content . ':' . self::VALUE_ContentIdLast)->setRecordField(self::FIELD_ContentHotel)
+            ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
+    }
+
     /**
      * @test
      * @see DataSet/changeParentContentRecordSorting.csv
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv
index 57676d2e07d3de79155b0028d24c7fcbfc92dc8e..f8e6da3c42a3b9b3630a6b1dca62e63c4a54e4d2 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv
@@ -4,7 +4,7 @@ pages
 ,88,1,256,0,0,0,0,0,0,0,0,0,DataHandlerTest,0,
 ,89,88,256,0,0,0,0,0,0,0,0,0,Relations,1,
 ,90,88,512,0,0,0,0,0,0,0,0,0,Target,0,
-,91,88,256,0,1,89,0,0,0,0,0,0,"[Translate to Dansk:] Relations",2,"{""url"":""parent"",""lastUpdated"":""parent"",""newUntil"":""parent"",""no_search"":""parent"",""shortcut"":""parent"",""shortcut_mode"":""parent"",""author"":""parent"",""author_email"":""parent"",""media"":""parent"",""tx_irretutorial_hotels"":""parent""}"
+,91,88,256,0,1,89,0,0,0,0,0,0,"[Translate to Dansk:] Relations",2,"{""url"":""parent"",""lastUpdated"":""parent"",""newUntil"":""parent"",""no_search"":""parent"",""shortcut"":""parent"",""shortcut_mode"":""parent"",""author"":""parent"",""author_email"":""parent"",""media"":""parent"",""tx_irretutorial_hotels"":""custom""}"
 tx_irretutorial_1nff_hotel
 ,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parentid,parenttable,parentidentifier,offers
 ,2,89,512,0,0,0,0,0,0,0,0,0,"Hotel #0",89,pages,,0