diff --git a/lib/modules/manager/maven/__fixtures__/multiple_usages_props.pom.xml b/lib/modules/manager/maven/__fixtures__/multiple_usages_props.pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2f58cfc2bfc750e577cdf435c7ffa30ada78e934
--- /dev/null
+++ b/lib/modules/manager/maven/__fixtures__/multiple_usages_props.pom.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.example</groupId>
+    <artifactId>ExamplePomFile</artifactId>
+
+    <properties>
+        <foo>1.2.3</foo>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.lucene</groupId>
+            <artifactId>lucene-core-${foo}.${foo}</artifactId>
+            <version>${foo}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/lib/modules/manager/maven/extract.ts b/lib/modules/manager/maven/extract.ts
index f7e95756969a94593b9d17c65acc83dd245c8b9d..4a5b8619045b05577ea8f0c08dfbb2fd1af228dd 100644
--- a/lib/modules/manager/maven/extract.ts
+++ b/lib/modules/manager/maven/extract.ts
@@ -33,7 +33,7 @@ export function parsePom(raw: string): XmlDocument | null {
 }
 
 function containsPlaceholder(str: string | null | undefined): boolean {
-  return !!str && regEx(/\${.*?}/g).test(str);
+  return !!str && regEx(/\${[^}]*?}/).test(str);
 }
 
 function depFromNode(
@@ -126,7 +126,7 @@ function applyProps(
 ): PackageDependency<Record<string, any>> {
   let result = dep;
   let anyChange = false;
-  const alreadySeenProps: string[] = [];
+  const alreadySeenProps: Set<string> = new Set();
 
   do {
     const [returnedResult, returnedAnyChange, fatal] = applyPropsInternal(
@@ -156,22 +156,24 @@ function applyPropsInternal(
   dep: PackageDependency<Record<string, any>>,
   depPackageFile: string,
   props: MavenProp,
-  alreadySeenProps: string[]
+  previouslySeenProps: Set<string>
 ): [PackageDependency<Record<string, any>>, boolean, boolean] {
   let anyChange = false;
   let fatal = false;
 
+  const seenProps: Set<string> = new Set();
+
   const replaceAll = (str: string): string =>
-    str.replace(regEx(/\${.*?}/g), (substr) => {
+    str.replace(regEx(/\${[^}]*?}/g), (substr) => {
       const propKey = substr.slice(2, -1).trim();
       // TODO: wrong types here, props is already `MavenProp`
       const propValue = (props as any)[propKey] as MavenProp;
       if (propValue) {
         anyChange = true;
-        if (alreadySeenProps.find((it) => it === propKey)) {
+        if (previouslySeenProps.has(propKey)) {
           fatal = true;
         } else {
-          alreadySeenProps.push(propKey);
+          seenProps.add(propKey);
         }
         return propValue.val;
       }
@@ -185,7 +187,7 @@ function applyPropsInternal(
   let propSource = dep.propSource;
   let groupName: string | null = null;
   const currentValue = dep.currentValue!.replace(
-    regEx(/^\${.*?}$/),
+    regEx(/^\${[^}]*?}$/),
     (substr) => {
       const propKey = substr.slice(2, -1).trim();
       // TODO: wrong types here, props is already `MavenProp`
@@ -197,10 +199,10 @@ function applyPropsInternal(
         fileReplacePosition = propValue.fileReplacePosition;
         propSource = propValue.packageFile ?? undefined;
         anyChange = true;
-        if (alreadySeenProps.find((it) => it === propKey)) {
+        if (previouslySeenProps.has(propKey)) {
           fatal = true;
         } else {
-          alreadySeenProps.push(propKey);
+          seenProps.add(propKey);
         }
         return propValue.val;
       }
@@ -225,6 +227,9 @@ function applyPropsInternal(
     result.editFile = propSource;
   }
 
+  for (const prop of seenProps) {
+    previouslySeenProps.add(prop);
+  }
   return [result, anyChange, fatal];
 }
 
diff --git a/lib/modules/manager/maven/index.spec.ts b/lib/modules/manager/maven/index.spec.ts
index a614327fdd737fa96ce0499fca798c0e14948122..6048157636e71600b157eff83a6ee899046fdf72 100644
--- a/lib/modules/manager/maven/index.spec.ts
+++ b/lib/modules/manager/maven/index.spec.ts
@@ -189,6 +189,18 @@ describe('modules/manager/maven/index', () => {
       ]);
     });
 
+    it('should apply props multiple times', () => {
+      const [{ deps }] = resolveParents([
+        extractPackage(Fixtures.get('multiple_usages_props.pom.xml'))!,
+      ]);
+      expect(deps).toMatchObject([
+        {
+          depName: 'org.apache.lucene:lucene-core-1.2.3.1.2.3',
+          currentValue: '1.2.3',
+        },
+      ]);
+    });
+
     it('should detect props infinitely recursing props', () => {
       const [{ deps }] = resolveParents([
         extractPackage(Fixtures.get('infinite_recursive_props.pom.xml'))!,