diff --git a/lib/config/presets/__snapshots__/index.spec.ts.snap b/lib/config/presets/__snapshots__/index.spec.ts.snap
index 526fe229dcc14b6ad2a5e89dc8f25ca34ff41b83..26cb932f6d6e26f6ec7c4bee13f70632a9feec84 100644
--- a/lib/config/presets/__snapshots__/index.spec.ts.snap
+++ b/lib/config/presets/__snapshots__/index.spec.ts.snap
@@ -487,6 +487,14 @@ Object {
 }
 `;
 
+exports[`config/presets resolvePreset resolves self-hosted presets without baseConfig 1`] = `
+Object {
+  "labels": Array [
+    "self-hosted resolved",
+  ],
+}
+`;
+
 exports[`config/presets resolvePreset returns same if no presets 1`] = `
 Object {
   "foo": 1,
diff --git a/lib/config/presets/index.spec.ts b/lib/config/presets/index.spec.ts
index bffa7bdfd80ad9d4e568d82babba4156afe91712..80c13d282bce4c14be498a3e66a49595bb5b8497 100644
--- a/lib/config/presets/index.spec.ts
+++ b/lib/config/presets/index.spec.ts
@@ -1,13 +1,16 @@
 import { RenovateConfig } from '..';
 import { mocked } from '../../../test/util';
 import presetIkatyang from './__fixtures__/renovate-config-ikatyang.json';
+import * as _local from './local';
 import * as _npm from './npm';
 import * as presets from '.';
 
 jest.mock('./npm');
 jest.mock('./github');
+jest.mock('./local');
 
 const npm = mocked(_npm);
+const local = mocked(_local);
 
 npm.getPreset = jest.fn(({ packageName, presetName }) => {
   if (packageName === 'renovate-config-ikatyang') {
@@ -177,6 +180,20 @@ describe('config/presets', () => {
       expect(config).toMatchObject(res);
       expect(res).toMatchSnapshot();
     });
+
+    it('resolves self-hosted presets without baseConfig', async () => {
+      config.extends = ['local>username/preset-repo'];
+      local.getPreset = jest.fn(({ packageName, presetName, baseConfig }) =>
+        Promise.resolve({ labels: ['self-hosted resolved'] })
+      );
+
+      const res = await presets.resolveConfigPresets(config);
+
+      expect(res.labels).toEqual(['self-hosted resolved']);
+      expect(local.getPreset.mock.calls).toHaveLength(1);
+      expect(local.getPreset.mock.calls[0][0].baseConfig).not.toBeUndefined();
+      expect(res).toMatchSnapshot();
+    });
   });
   describe('replaceArgs', () => {
     const argMappings = {
diff --git a/lib/config/presets/index.ts b/lib/config/presets/index.ts
index d48fb6a0e7442f31a6c3fd1cdac80807bc9c80fc..a6e1ddea58647e79ebbeae0779e18ba6b688d689 100644
--- a/lib/config/presets/index.ts
+++ b/lib/config/presets/index.ts
@@ -214,7 +214,7 @@ export async function resolveConfigPresets(
         logger.trace(`Resolving preset "${preset}"`);
         let fetchedPreset: RenovateConfig;
         try {
-          fetchedPreset = await getPreset(preset, baseConfig);
+          fetchedPreset = await getPreset(preset, baseConfig ?? inputConfig);
         } catch (err) {
           logger.debug({ preset, err }, 'Preset fetch error');
           // istanbul ignore if