diff --git a/lib/modules/manager/gradle/extract.spec.ts b/lib/modules/manager/gradle/extract.spec.ts
index 249c959102a603c882c1170c9f16206545e8c105..c63b0e3a6634eb10ad7dc596bdea314cdeac75b7 100644
--- a/lib/modules/manager/gradle/extract.spec.ts
+++ b/lib/modules/manager/gradle/extract.spec.ts
@@ -242,11 +242,7 @@ describe('modules/manager/gradle/extract', () => {
           deps: [
             {
               depType: 'plugin',
-              registryUrls: [
-                'https://repo.maven.apache.org/maven2',
-                'https://example.com',
-                'https://plugins.gradle.org/m2/',
-              ],
+              registryUrls: ['https://plugins.gradle.org/m2/'],
             },
             {
               registryUrls: [
@@ -314,6 +310,65 @@ describe('modules/manager/gradle/extract', () => {
         },
       ]);
     });
+
+    it('supports separate registry URLs for plugins', async () => {
+      const settingsFile = codeBlock`
+        pluginManagement {
+          repositories {
+            mavenLocal()
+            maven { url = "https://foo.bar/plugins" }
+          }
+        }
+      `;
+
+      const buildFile = codeBlock`
+        plugins {
+          id "foo.bar" version "1.2.3"
+        }
+        repositories {
+          maven { url = "https://foo.bar/deps" }
+          mavenCentral()
+        }
+        dependencies {
+          classpath "io.jsonwebtoken:jjwt-api:0.11.2"
+        }
+      `;
+
+      const fsMock = {
+        'build.gradle': buildFile,
+        'settings.gradle': settingsFile,
+      };
+      mockFs(fsMock);
+
+      const res = await extractAllPackageFiles(
+        {} as ExtractConfig,
+        Object.keys(fsMock)
+      );
+
+      expect(res).toMatchObject([
+        {
+          packageFile: 'settings.gradle',
+          deps: [],
+        },
+        {
+          packageFile: 'build.gradle',
+          deps: [
+            {
+              depName: 'foo.bar',
+              depType: 'plugin',
+              registryUrls: ['https://foo.bar/plugins'],
+            },
+            {
+              depName: 'io.jsonwebtoken:jjwt-api',
+              registryUrls: [
+                'https://foo.bar/deps',
+                'https://repo.maven.apache.org/maven2',
+              ],
+            },
+          ],
+        },
+      ]);
+    });
   });
 
   describe('version catalogs', () => {
diff --git a/lib/modules/manager/gradle/extract.ts b/lib/modules/manager/gradle/extract.ts
index f3ff86968dd9511370e4599bd798d63a4409708a..7053716f06ed30af009a00442c8ea73f51fd3d23 100644
--- a/lib/modules/manager/gradle/extract.ts
+++ b/lib/modules/manager/gradle/extract.ts
@@ -10,8 +10,10 @@ import {
   usesGcv,
 } from './extract/consistent-versions-plugin';
 import { parseGradle, parseProps } from './parser';
+import { REGISTRY_URLS } from './parser/common';
 import type {
   GradleManagerData,
+  PackageRegistry,
   PackageVariables,
   VariableRegistry,
 } from './types';
@@ -26,6 +28,23 @@ import {
 
 const datasource = MavenDatasource.id;
 
+function getRegistryUrlsForDep(
+  packageRegistries: PackageRegistry[],
+  dep: PackageDependency<GradleManagerData>
+): string[] {
+  const scope = dep.depType === 'plugin' ? 'plugin' : 'dep';
+
+  const registryUrls = packageRegistries
+    .filter((item) => item.scope === scope)
+    .map((item) => item.registryUrl);
+
+  if (!registryUrls.length && scope === 'plugin') {
+    registryUrls.push(REGISTRY_URLS.gradlePluginPortal);
+  }
+
+  return [...new Set(registryUrls)];
+}
+
 export async function extractAllPackageFiles(
   config: ExtractConfig,
   packageFiles: string[]
@@ -33,7 +52,7 @@ export async function extractAllPackageFiles(
   const extractedDeps: PackageDependency<GradleManagerData>[] = [];
   const varRegistry: VariableRegistry = {};
   const packageFilesByName: Record<string, PackageFile> = {};
-  const packageRegistries: string[] = [];
+  const packageRegistries: PackageRegistry[] = [];
   const reorderedFiles = reorderFiles(packageFiles);
   const fileContents = await getFileContentMap(packageFiles, true);
 
@@ -75,7 +94,11 @@ export async function extractAllPackageFiles(
           vars: gradleVars,
         } = parseGradle(content, vars, packageFile, fileContents);
         for (const url of urls) {
-          if (!packageRegistries.includes(url)) {
+          const registryAlreadyKnown = packageRegistries.some(
+            (item) =>
+              item.registryUrl === url.registryUrl && item.scope === url.scope
+          );
+          if (!registryAlreadyKnown) {
             packageRegistries.push(url);
           }
         }
@@ -114,9 +137,7 @@ export async function extractAllPackageFiles(
         };
       }
 
-      dep.registryUrls = [
-        ...new Set([...packageRegistries, ...(dep.registryUrls ?? [])]),
-      ];
+      dep.registryUrls = getRegistryUrlsForDep(packageRegistries, dep);
 
       if (!dep.depType) {
         dep.depType = key.startsWith('buildSrc')
diff --git a/lib/modules/manager/gradle/extract/catalog.ts b/lib/modules/manager/gradle/extract/catalog.ts
index 69d7bb10c9d5ebc520b1d580418bc52ff861dc98..49b21ccceea7bc1f545a21f4eda01013089492b6 100644
--- a/lib/modules/manager/gradle/extract/catalog.ts
+++ b/lib/modules/manager/gradle/extract/catalog.ts
@@ -276,7 +276,6 @@ export function parseCatalog(
       depType: 'plugin',
       depName,
       packageName: `${depName}:${depName}.gradle.plugin`,
-      registryUrls: ['https://plugins.gradle.org/m2/'],
       currentValue,
       commitMessageTopic: `plugin ${pluginName}`,
       managerData: { fileReplacePosition },
diff --git a/lib/modules/manager/gradle/parser.spec.ts b/lib/modules/manager/gradle/parser.spec.ts
index 4734a6cbca7e0c59495f50cb8979f550deb9400d..efeecbbd0c1f59157609b7da52e1fdebf5eae902 100644
--- a/lib/modules/manager/gradle/parser.spec.ts
+++ b/lib/modules/manager/gradle/parser.spec.ts
@@ -545,7 +545,7 @@ describe('modules/manager/gradle/parser', () => {
         ${'jcenter()'}                                 | ${REGISTRY_URLS.jcenter}
       `('$input', ({ input, output }) => {
         const { urls } = parseGradle(input);
-        expect(urls).toStrictEqual([output].filter(Boolean));
+        expect(urls).toMatchObject([{ registryUrl: output }]);
       });
     });
 
@@ -587,11 +587,60 @@ describe('modules/manager/gradle/parser', () => {
         ${''}                       | ${'maven { setUrl("foo", "bar") }'}                              | ${null}
         ${'base="https://foo.bar"'} | ${'publishing { repositories { maven("${base}/baz") } }'}        | ${null}
       `('$def | $input', ({ def, input, url }) => {
-        const expected = [url].filter(Boolean);
+        const expected = url ? [{ registryUrl: url }] : [];
         const { urls } = parseGradle([def, input].join('\n'));
-        expect(urls).toStrictEqual(expected);
+        expect(urls).toMatchObject(expected);
       });
     });
+
+    it('pluginManagement', () => {
+      const input = codeBlock`
+          pluginManagement {
+            def fooVersion = "1.2.3"
+            repositories {
+              mavenLocal()
+              maven { url = "https://foo.bar/plugins" }
+              gradlePluginPortal()
+            }
+            plugins {
+              id("foo.bar") version "$fooVersion"
+            }
+          }
+          dependencyResolutionManagement {
+            repositories {
+              maven { url = "https://foo.bar/deps" }
+              mavenCentral()
+            }
+          }
+        `;
+
+      const { deps, urls } = parseGradle(input);
+      expect(deps).toMatchObject([
+        {
+          depType: 'plugin',
+          depName: 'foo.bar',
+          currentValue: '1.2.3',
+        },
+      ]);
+      expect(urls).toMatchObject([
+        {
+          registryUrl: 'https://foo.bar/plugins',
+          scope: 'plugin',
+        },
+        {
+          registryUrl: REGISTRY_URLS.gradlePluginPortal,
+          scope: 'plugin',
+        },
+        {
+          registryUrl: 'https://foo.bar/deps',
+          scope: 'dep',
+        },
+        {
+          registryUrl: REGISTRY_URLS.mavenCentral,
+          scope: 'dep',
+        },
+      ]);
+    });
   });
 
   describe('version catalog', () => {
diff --git a/lib/modules/manager/gradle/parser.ts b/lib/modules/manager/gradle/parser.ts
index ec245fa0c07a68feb19ad6e5e44cb5b2459a2d96..44fd6066b4f2c831ebbf878e3b371d0219eb88f7 100644
--- a/lib/modules/manager/gradle/parser.ts
+++ b/lib/modules/manager/gradle/parser.ts
@@ -10,6 +10,7 @@ import { qVersionCatalogs } from './parser/version-catalogs';
 import type {
   Ctx,
   GradleManagerData,
+  PackageRegistry,
   PackageVariables,
   ParseGradleResult,
 } from './types';
@@ -26,7 +27,7 @@ export function parseGradle(
 ): ParseGradleResult {
   let vars: PackageVariables = { ...initVars };
   const deps: PackageDependency<GradleManagerData>[] = [];
-  const urls: string[] = [];
+  const urls: PackageRegistry[] = [];
 
   const query = q.tree<Ctx>({
     type: 'root-tree',
diff --git a/lib/modules/manager/gradle/parser/handlers.ts b/lib/modules/manager/gradle/parser/handlers.ts
index 043a896ddcaf5b23dfead1e07b67cf93e834a10a..c4721ead81db1bb4f521ef5cc7b6030d03a41cf2 100644
--- a/lib/modules/manager/gradle/parser/handlers.ts
+++ b/lib/modules/manager/gradle/parser/handlers.ts
@@ -216,7 +216,6 @@ export function handlePlugin(ctx: Ctx): Ctx {
     depType: 'plugin',
     depName,
     packageName,
-    registryUrls: [REGISTRY_URLS.gradlePluginPortal],
     commitMessageTopic: `plugin ${depName}`,
     currentValue: pluginVersion[0].value,
     managerData: {
@@ -246,11 +245,22 @@ export function handlePlugin(ctx: Ctx): Ctx {
   return ctx;
 }
 
+function isPluginRegistry(ctx: Ctx): boolean {
+  if (ctx.tokenMap.registryScope) {
+    const registryScope = loadFromTokenMap(ctx, 'registryScope')[0].value;
+    return registryScope === 'pluginManagement';
+  }
+
+  return false;
+}
+
 export function handlePredefinedRegistryUrl(ctx: Ctx): Ctx {
   const registryName = loadFromTokenMap(ctx, 'registryUrl')[0].value;
-  ctx.registryUrls.push(
-    REGISTRY_URLS[registryName as keyof typeof REGISTRY_URLS]
-  );
+
+  ctx.registryUrls.push({
+    registryUrl: REGISTRY_URLS[registryName as keyof typeof REGISTRY_URLS],
+    scope: isPluginRegistry(ctx) ? 'plugin' : 'dep',
+  });
 
   return ctx;
 }
@@ -281,7 +291,10 @@ export function handleCustomRegistryUrl(ctx: Ctx): Ctx {
     try {
       const { host, protocol } = url.parse(registryUrl);
       if (host && protocol) {
-        ctx.registryUrls.push(registryUrl);
+        ctx.registryUrls.push({
+          registryUrl,
+          scope: isPluginRegistry(ctx) ? 'plugin' : 'dep',
+        });
       }
     } catch (e) {
       // no-op
diff --git a/lib/modules/manager/gradle/parser/registry-urls.ts b/lib/modules/manager/gradle/parser/registry-urls.ts
index 7a2011b7e46203b0993e79e20bfca25797101bec..3cae44e44b888447ac009cad8bd98cf8428b5674 100644
--- a/lib/modules/manager/gradle/parser/registry-urls.ts
+++ b/lib/modules/manager/gradle/parser/registry-urls.ts
@@ -1,6 +1,8 @@
 import { query as q } from 'good-enough-parser';
 import { regEx } from '../../../../util/regex';
 import type { Ctx } from '../types';
+import { qApplyFrom } from './apply-from';
+import { qAssignments } from './assignments';
 import {
   REGISTRY_URLS,
   cleanupTempVars,
@@ -13,6 +15,7 @@ import {
   handleCustomRegistryUrl,
   handlePredefinedRegistryUrl,
 } from './handlers';
+import { qPlugins } from './plugins';
 
 // mavenCentral()
 // mavenCentral { ... }
@@ -94,8 +97,38 @@ const qCustomRegistryUrl = q
   .handler(handleCustomRegistryUrl)
   .handler(cleanupTempVars);
 
+const qPluginManagement = q.sym<Ctx>('pluginManagement', storeVarToken).tree({
+  type: 'wrapped-tree',
+  startsWith: '{',
+  endsWith: '}',
+  preHandler: (ctx) => {
+    ctx.tmpTokenStore.registryScope = ctx.varTokens;
+    ctx.varTokens = [];
+    return ctx;
+  },
+  search: q
+    .handler<Ctx>((ctx) => {
+      if (ctx.tmpTokenStore.registryScope) {
+        ctx.tokenMap.registryScope = ctx.tmpTokenStore.registryScope;
+      }
+      return ctx;
+    })
+    .alt(
+      qAssignments,
+      qApplyFrom,
+      qPlugins,
+      qPredefinedRegistries,
+      qCustomRegistryUrl
+    ),
+  postHandler: (ctx) => {
+    delete ctx.tmpTokenStore.registryScope;
+    return ctx;
+  },
+});
+
 export const qRegistryUrls = q.alt<Ctx>(
   q.sym<Ctx>('publishing').tree(),
+  qPluginManagement,
   qPredefinedRegistries,
   qCustomRegistryUrl
 );
diff --git a/lib/modules/manager/gradle/types.ts b/lib/modules/manager/gradle/types.ts
index d68c39cd30dba6fe938997610bc4e14e76bbb426..a4646dbef8ab8619c1c57b93fee1ee330493ceff 100644
--- a/lib/modules/manager/gradle/types.ts
+++ b/lib/modules/manager/gradle/types.ts
@@ -16,7 +16,7 @@ export type VariableRegistry = Record<string, PackageVariables>;
 
 export interface ParseGradleResult {
   deps: PackageDependency<GradleManagerData>[];
-  urls: string[];
+  urls: PackageRegistry[];
   vars: PackageVariables;
 }
 
@@ -67,6 +67,11 @@ export interface RichVersion {
 export type GradleVersionPointerTarget = string | RichVersion;
 export type GradleVersionCatalogVersion = string | VersionPointer | RichVersion;
 
+export interface PackageRegistry {
+  registryUrl: string;
+  scope: 'dep' | 'plugin';
+}
+
 export interface Ctx {
   readonly packageFile: string;
   readonly fileContents: Record<string, string | null>;
@@ -74,7 +79,7 @@ export interface Ctx {
 
   globalVars: PackageVariables;
   deps: PackageDependency<GradleManagerData>[];
-  registryUrls: string[];
+  registryUrls: PackageRegistry[];
 
   varTokens: lexer.Token[];
   tmpTokenStore: Record<string, lexer.Token[]>;