diff --git a/lib/modules/datasource/datasource.ts b/lib/modules/datasource/datasource.ts
index eb9ffa1ce8e9495fea5144760cecda1d600839c4..3d7fa807a3be69347f5aae6f0401ddcd4227b197 100644
--- a/lib/modules/datasource/datasource.ts
+++ b/lib/modules/datasource/datasource.ts
@@ -19,7 +19,7 @@ export abstract class Datasource implements DatasourceApi {
 
   defaultConfig: Record<string, unknown> | undefined;
 
-  defaultRegistryUrls: string[] | undefined;
+  defaultRegistryUrls?: string[] | (() => string[]);
 
   defaultVersioning: string | undefined;
 
diff --git a/lib/modules/datasource/index.spec.ts b/lib/modules/datasource/index.spec.ts
index c2054c683a693f024b0ce7c938dd2086cc3d5f69..ace1cba910a42d29885f4e5700a1c55e5792ab06 100644
--- a/lib/modules/datasource/index.spec.ts
+++ b/lib/modules/datasource/index.spec.ts
@@ -43,6 +43,47 @@ class DummyDatasource extends Datasource {
   }
 }
 
+class DummyDatasource2 extends Datasource {
+  override defaultRegistryUrls = function () {
+    return ['https://reg1.com'];
+  };
+
+  constructor(private registriesMock: RegistriesMock = defaultRegistriesMock) {
+    super(datasource);
+  }
+
+  override getReleases({
+    registryUrl,
+  }: GetReleasesConfig): Promise<ReleaseResult | null> {
+    const fn = this.registriesMock[registryUrl];
+    if (typeof fn === 'function') {
+      return Promise.resolve(fn());
+    }
+    return Promise.resolve(fn ?? null);
+  }
+}
+
+class DummyDatasource3 extends Datasource {
+  override customRegistrySupport = false;
+  override defaultRegistryUrls = function () {
+    return ['https://reg1.com'];
+  };
+
+  constructor(private registriesMock: RegistriesMock = defaultRegistriesMock) {
+    super(datasource);
+  }
+
+  override getReleases({
+    registryUrl,
+  }: GetReleasesConfig): Promise<ReleaseResult | null> {
+    const fn = this.registriesMock[registryUrl];
+    if (typeof fn === 'function') {
+      return Promise.resolve(fn());
+    }
+    return Promise.resolve(fn ?? null);
+  }
+}
+
 jest.mock('./metadata-manual', () => ({
   manualChangelogUrls: {
     dummy: {
@@ -212,6 +253,30 @@ describe('modules/datasource/index', () => {
       expect(res).toMatchObject({ releases: [{ version: '0.0.1' }] });
     });
 
+    it('defaultRegistryUrls function works', async () => {
+      datasources.set(datasource, new DummyDatasource2());
+      const res = await getPkgReleases({
+        datasource,
+        depName,
+      });
+      expect(res).toMatchObject({
+        releases: [{ version: '1.2.3' }],
+        registryUrl: 'https://reg1.com',
+      });
+    });
+
+    it('defaultRegistryUrls function with customRegistrySupport works', async () => {
+      datasources.set(datasource, new DummyDatasource3());
+      const res = await getPkgReleases({
+        datasource,
+        depName,
+      });
+      expect(res).toMatchObject({
+        releases: [{ version: '1.2.3' }],
+        registryUrl: 'https://reg1.com',
+      });
+    });
+
     it('applies extractVersion', async () => {
       const registries: RegistriesMock = {
         'https://reg1.com': {
diff --git a/lib/modules/datasource/index.ts b/lib/modules/datasource/index.ts
index b55b1c2e1a76dd9691a4080bab5dba526b2e522a..ece88626ad22019e0c949f9d2d99b84b38f17683 100644
--- a/lib/modules/datasource/index.ts
+++ b/lib/modules/datasource/index.ts
@@ -209,7 +209,9 @@ function resolveRegistryUrls(
         'Custom registries are not allowed for this datasource and will be ignored'
       );
     }
-    return datasource.defaultRegistryUrls ?? [];
+    return is.function_(datasource.defaultRegistryUrls)
+      ? datasource.defaultRegistryUrls()
+      : datasource.defaultRegistryUrls ?? [];
   }
   const customUrls = registryUrls?.filter(Boolean);
   let resolvedUrls: string[] = [];
@@ -218,6 +220,9 @@ function resolveRegistryUrls(
   } else if (is.nonEmptyArray(defaultRegistryUrls)) {
     resolvedUrls = [...defaultRegistryUrls];
     resolvedUrls.concat(additionalRegistryUrls ?? []);
+  } else if (is.function_(datasource.defaultRegistryUrls)) {
+    resolvedUrls = [...datasource.defaultRegistryUrls()];
+    resolvedUrls.concat(additionalRegistryUrls ?? []);
   } else if (is.nonEmptyArray(datasource.defaultRegistryUrls)) {
     resolvedUrls = [...datasource.defaultRegistryUrls];
     resolvedUrls.concat(additionalRegistryUrls ?? []);
diff --git a/lib/modules/datasource/types.ts b/lib/modules/datasource/types.ts
index be5e106ec04fd280cce822af4c6e0b3954502ecf..867c8829f11936b76ee4a380de43c5d1eb6941a8 100644
--- a/lib/modules/datasource/types.ts
+++ b/lib/modules/datasource/types.ts
@@ -76,7 +76,7 @@ export interface DatasourceApi extends ModuleApi {
   id: string;
   getDigest?(config: DigestConfig, newValue?: string): Promise<string | null>;
   getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null>;
-  defaultRegistryUrls?: string[];
+  defaultRegistryUrls?: string[] | (() => string[]);
   defaultVersioning?: string;
   defaultConfig?: Record<string, unknown>;