diff --git a/lib/modules/manager/maven/extract.spec.ts b/lib/modules/manager/maven/extract.spec.ts
index 3ff8e84aaec9d0e176272f8f408a34346fad9c2c..d6689de4238d701d2cb06028bb6373a4ad30db28 100644
--- a/lib/modules/manager/maven/extract.spec.ts
+++ b/lib/modules/manager/maven/extract.spec.ts
@@ -3,6 +3,7 @@ import { Fixtures } from '../../../../test/fixtures';
 import { fs } from '../../../../test/util';
 import {
   extractAllPackageFiles,
+  extractExtensions,
   extractPackage,
   extractRegistries,
   resolveParents,
@@ -365,6 +366,27 @@ describe('modules/manager/maven/extract', () => {
     });
   });
 
+  describe('extractExtensions', () => {
+    it('returns null for invalid xml files', () => {
+      expect(extractExtensions('', '.mvn/extensions.xml')).toBeNull();
+      expect(
+        extractExtensions('invalid xml content', '.mvn/extensions.xml'),
+      ).toBeNull();
+      expect(
+        extractExtensions('<foobar></foobar>', '.mvn/extensions.xml'),
+      ).toBeNull();
+      expect(
+        extractExtensions('<extensions></extensions>', '.mvn/extensions.xml'),
+      ).toBeNull();
+      expect(
+        extractExtensions(
+          '<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0"></extensions>',
+          '.mvn/extensions.xml',
+        ),
+      ).toBeNull();
+    });
+  });
+
   describe('extractAllPackageFiles', () => {
     it('should return empty if package has no content', async () => {
       fs.readLocalFile.mockResolvedValueOnce('');
@@ -706,6 +728,47 @@ describe('modules/manager/maven/extract', () => {
       ]);
     });
 
+    it('should extract from .mvn/extensions.xml file', async () => {
+      fs.readLocalFile.mockResolvedValueOnce(codeBlock`
+      <extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">
+        <extension>
+          <groupId>io.jenkins.tools.incrementals</groupId>
+          <artifactId>git-changelist-maven-extension</artifactId>
+          <version>1.6</version>
+        </extension>
+      </extensions>
+    `);
+      const res = await extractAllPackageFiles({}, ['.mvn/extensions.xml']);
+      expect(res).toMatchObject([
+        {
+          packageFile: '.mvn/extensions.xml',
+          deps: [
+            {
+              datasource: 'maven',
+              depName:
+                'io.jenkins.tools.incrementals:git-changelist-maven-extension',
+              currentValue: '1.6',
+              depType: 'build',
+              fileReplacePosition: 372,
+              registryUrls: ['https://repo.maven.apache.org/maven2'],
+            },
+          ],
+        },
+      ]);
+    });
+
+    it('should return empty array if extensions file is invalid or empty', async () => {
+      fs.readLocalFile
+        .mockResolvedValueOnce('')
+        .mockResolvedValueOnce('invalid xml content');
+      expect(
+        await extractAllPackageFiles({}, [
+          '.mvn/extensions.xml',
+          'grp/.mvn/extensions.xml',
+        ]),
+      ).toBeEmptyArray();
+    });
+
     describe('root pom handling', () => {
       it('should skip root pom.xml', async () => {
         fs.readLocalFile.mockResolvedValueOnce(codeBlock`
diff --git a/lib/modules/manager/maven/extract.ts b/lib/modules/manager/maven/extract.ts
index 061c28fd92160d9ffa6308fffcd3ceff70692e2e..c19b2de1c42df86da9f21e9e245ca9c311471a7d 100644
--- a/lib/modules/manager/maven/extract.ts
+++ b/lib/modules/manager/maven/extract.ts
@@ -15,6 +15,12 @@ const supportedNamespaces = [
   'http://maven.apache.org/SETTINGS/1.2.0',
 ];
 
+const supportedExtensionsNamespaces = [
+  'http://maven.apache.org/EXTENSIONS/1.0.0',
+  'http://maven.apache.org/EXTENSIONS/1.1.0',
+  'http://maven.apache.org/EXTENSIONS/1.2.0',
+];
+
 function parsePom(raw: string, packageFile: string): XmlDocument | null {
   let project: XmlDocument;
   try {
@@ -39,6 +45,27 @@ function parsePom(raw: string, packageFile: string): XmlDocument | null {
   return null;
 }
 
+function parseExtensions(raw: string, packageFile: string): XmlDocument | null {
+  let extensions: XmlDocument;
+  try {
+    extensions = new XmlDocument(raw);
+  } catch (err) {
+    logger.debug({ packageFile }, `Failed to parse as XML`);
+    return null;
+  }
+  const { name, attr, children } = extensions;
+  if (name !== 'extensions') {
+    return null;
+  }
+  if (!supportedExtensionsNamespaces.includes(attr.xmlns)) {
+    return null;
+  }
+  if (!is.nonEmptyArray(children)) {
+    return null;
+  }
+  return extensions;
+}
+
 function containsPlaceholder(str: string | null | undefined): boolean {
   return !!str && regEx(/\${[^}]*?}/).test(str);
 }
@@ -476,6 +503,30 @@ function cleanResult(packageFiles: MavenInterimPackageFile[]): PackageFile[] {
   return packageFiles;
 }
 
+export function extractExtensions(
+  rawContent: string,
+  packageFile: string,
+): PackageFile | null {
+  if (!rawContent) {
+    return null;
+  }
+
+  const extensions = parseExtensions(rawContent, packageFile);
+  if (!extensions) {
+    return null;
+  }
+
+  const result: MavenInterimPackageFile = {
+    datasource: MavenDatasource.id,
+    packageFile,
+    deps: [],
+  };
+
+  result.deps = deepExtract(extensions);
+
+  return result;
+}
+
 export async function extractAllPackageFiles(
   _config: ExtractConfig,
   packageFiles: string[],
@@ -498,6 +549,13 @@ export async function extractAllPackageFiles(
         );
         additionalRegistryUrls.push(...registries);
       }
+    } else if (packageFile.endsWith('.mvn/extensions.xml')) {
+      const extensions = extractExtensions(content, packageFile);
+      if (extensions) {
+        packages.push(extensions);
+      } else {
+        logger.trace({ packageFile }, 'can not read extensions');
+      }
     } else {
       const pkg = extractPackage(content, packageFile);
       if (pkg) {
diff --git a/lib/modules/manager/maven/index.ts b/lib/modules/manager/maven/index.ts
index 8d12ca432bb60642800aa7962861967912b39f35..bd282a23395db6e8862232c8b3cf440ea85ebcc4 100644
--- a/lib/modules/manager/maven/index.ts
+++ b/lib/modules/manager/maven/index.ts
@@ -6,7 +6,11 @@ export { extractAllPackageFiles } from './extract';
 export { bumpPackageVersion, updateDependency } from './update';
 
 export const defaultConfig = {
-  fileMatch: ['(^|/|\\.)pom\\.xml$', '^(((\\.mvn)|(\\.m2))/)?settings\\.xml$'],
+  fileMatch: [
+    '(^|/|\\.)pom\\.xml$',
+    '^(((\\.mvn)|(\\.m2))/)?settings\\.xml$',
+    '(^|/)\\.mvn/extensions\\.xml$',
+  ],
   versioning: mavenVersioning.id,
 };