diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php
index c52c28d78e7d5b5569881a6340e6cb263d74e702..113556477d6d8c69509bad7cc01408f53346d0d5 100644
--- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php
+++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php
@@ -755,6 +755,35 @@ class DataHandler implements LoggerAwareInterface
         }
     }
 
+    /**
+     * When a new record is created, all values that haven't been set but are set via PageTSconfig / UserTSconfig
+     * get applied here.
+     *
+     * This is only executed for new records. The most important part is that the pageTS of the actual resolved $pid
+     * is taken, and a new field array with empty defaults is set again.
+     *
+     * @param string $table
+     * @param int $pageId
+     * @param array $prepopulatedFieldArray
+     * @return array
+     */
+    protected function applyDefaultsForFieldArray(string $table, int $pageId, array $prepopulatedFieldArray): array
+    {
+        // First set TCAdefaults respecting the given PageID
+        $tcaDefaults = BackendUtility::getPagesTSconfig($pageId)['TCAdefaults.'] ?? null;
+        // Re-apply $this->defaultValues settings
+        $this->setDefaultsFromUserTS($tcaDefaults);
+        $cleanFieldArray = $this->newFieldArray($table);
+        if (isset($prepopulatedFieldArray['pid'])) {
+            $cleanFieldArray['pid'] = $prepopulatedFieldArray['pid'];
+        }
+        $sortColumn = $GLOBALS['TCA'][$table]['ctrl']['sortby'] ?? null;
+        if ($sortColumn !== null && isset($prepopulatedFieldArray[$sortColumn])) {
+            $cleanFieldArray[$sortColumn] = $prepopulatedFieldArray[$sortColumn];
+        }
+        return $cleanFieldArray;
+    }
+
     /**
      * Dummy method formerly used for file handling.
      *
@@ -1049,13 +1078,18 @@ class DataHandler implements LoggerAwareInterface
 
                 // Here the "pid" is set IF NOT the old pid was a string pointing to a place in the subst-id array.
                 [$tscPID] = BackendUtility::getTSCpid($table, $id, $old_pid_value ?: $fieldArray['pid']);
-                if ($status === 'new' && $table === 'pages') {
-                    $fieldArray = $this->pagePermissionAssembler->applyDefaults(
-                        $fieldArray,
-                        (int)$tscPID,
-                        (int)$this->userid,
-                        (int)$this->BE_USER->firstMainGroup
-                    );
+                if ($status === 'new') {
+                    // Apply TCAdefaults from pageTS
+                    $fieldArray = $this->applyDefaultsForFieldArray($table, (int)$tscPID, $fieldArray);
+                    // Apply page permissions as well
+                    if ($table === 'pages') {
+                        $fieldArray = $this->pagePermissionAssembler->applyDefaults(
+                            $fieldArray,
+                            (int)$tscPID,
+                            (int)$this->userid,
+                            (int)$this->BE_USER->firstMainGroup
+                        );
+                    }
                 }
                 // Processing of all fields in incomingFieldArray and setting them in $fieldArray
                 $fieldArray = $this->fillInFieldArray($table, $id, $fieldArray, $incomingFieldArray, $theRealPid, $status, $tscPID);
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DefaultValuesTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DefaultValuesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..698cc70afa95938b2c6e00428b43e2c0082f5129
--- /dev/null
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DefaultValuesTest.php
@@ -0,0 +1,147 @@
+<?php
+declare(strict_types = 1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler;
+
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
+use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+
+/**
+ * Tests various places to set default values properly for new records
+ */
+class DefaultValuesTest extends AbstractDataHandlerActionTestCase
+{
+    /**
+     * @var int
+     */
+    const PAGE_DATAHANDLER = 88;
+
+    /**
+     * @var string
+     */
+    protected $scenarioDataSetDirectory = 'typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DataSet/';
+
+    protected function setUp(): void
+    {
+        parent::setUp();
+        $this->importScenarioDataSet('LiveDefaultPages');
+        $this->importScenarioDataSet('LiveDefaultElements');
+        $this->backendUser->workspace = 0;
+    }
+
+    /**
+     * @test
+     */
+    public function defaultValuesFromTCAForNewRecordsIsRespected(): void
+    {
+        $GLOBALS['TCA']['pages']['columns']['keywords']['config']['default'] = 'a few,random,keywords';
+        $map = $this->actionService->createNewRecord('pages', self::PAGE_DATAHANDLER, [
+            'title' => 'A new age'
+        ]);
+        $newPageId = reset($map['pages']);
+        $newPageRecord = BackendUtility::getRecord('pages', $newPageId);
+        self::assertEquals($newPageRecord['keywords'], $GLOBALS['TCA']['pages']['columns']['keywords']['config']['default']);
+
+        $GLOBALS['TCA']['tt_content']['columns']['header']['config']['default'] = 'Pre-set header';
+        $map = $this->actionService->createNewRecord('tt_content', $newPageId, [
+            'header' => '',
+            'bodytext' => 'Random bodytext'
+        ]);
+        $newContentId = reset($map['tt_content']);
+        $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId);
+        // Empty header is used, because it was handed in
+        self::assertEquals($newContentRecord['header'], '');
+
+        $map = $this->actionService->createNewRecord('tt_content', $newPageId, [
+            'bodytext' => 'Random bodytext'
+        ]);
+        $newContentId = reset($map['tt_content']);
+        $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId);
+        self::assertEquals($newContentRecord['header'], $GLOBALS['TCA']['tt_content']['columns']['header']['config']['default']);
+    }
+
+    /**
+     * @test
+     */
+    public function defaultValuesFromGlobalTSconfigForNewRecordsIsRespected(): void
+    {
+        ExtensionManagementUtility::addPageTSConfig('
+TCAdefaults.pages.keywords = from pagets, with love
+TCAdefaults.tt_content.header = global space');
+        $map = $this->actionService->createNewRecord('pages', self::PAGE_DATAHANDLER, [
+            'title' => 'A new age'
+        ]);
+        $newPageId = reset($map['pages']);
+        $newPageRecord = BackendUtility::getRecord('pages', $newPageId);
+        self::assertEquals($newPageRecord['keywords'], 'from pagets, with love');
+
+        $map = $this->actionService->createNewRecord('tt_content', $newPageId, [
+            'header' => '',
+            'bodytext' => 'Random bodytext'
+        ]);
+        $newContentId = reset($map['tt_content']);
+        $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId);
+        // Empty header is used, because it was handed in
+        self::assertEquals($newContentRecord['header'], '');
+
+        $map = $this->actionService->createNewRecord('tt_content', $newPageId, [
+            'bodytext' => 'Random bodytext'
+        ]);
+        $newContentId = reset($map['tt_content']);
+        $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId);
+        self::assertEquals($newContentRecord['header'], 'global space');
+    }
+
+    /**
+     * @test
+     */
+    public function defaultValuesFromPageSpecificTSconfigForNewRecordsIsRespected(): void
+    {
+        ExtensionManagementUtility::addPageTSConfig('
+TCAdefaults.pages.keywords = from pagets, with love
+TCAdefaults.tt_content.header = global space');
+        $this->actionService->modifyRecord('pages', self::PAGE_DATAHANDLER, [
+            'TSconfig' => '
+
+TCAdefaults.pages.keywords = I am specific, not generic
+TCAdefaults.tt_content.header = local space
+
+']);
+        $map = $this->actionService->createNewRecord('pages', self::PAGE_DATAHANDLER, [
+            'title' => 'A new age'
+        ]);
+        $newPageId = reset($map['pages']);
+        $newPageRecord = BackendUtility::getRecord('pages', $newPageId);
+        self::assertEquals($newPageRecord['keywords'], 'I am specific, not generic');
+
+        $map = $this->actionService->createNewRecord('tt_content', $newPageId, [
+            'header' => '',
+            'bodytext' => 'Random bodytext'
+        ]);
+        $newContentId = reset($map['tt_content']);
+        $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId);
+        // Empty header is used, because it was handed in
+        self::assertEquals($newContentRecord['header'], '');
+
+        $map = $this->actionService->createNewRecord('tt_content', $newPageId, [
+            'bodytext' => 'Random bodytext'
+        ]);
+        $newContentId = reset($map['tt_content']);
+        $newContentRecord = BackendUtility::getRecord('tt_content', $newContentId);
+        self::assertEquals($newContentRecord['header'], 'local space');
+    }
+}