diff --git a/lib/modules/manager/npm/extract/locked-versions.spec.ts b/lib/modules/manager/npm/extract/locked-versions.spec.ts
index 6f411397e710f0bed56c34ed55065a026824ce37..bbac5fcacafef5619c5528fd5e874191a0beaa13 100644
--- a/lib/modules/manager/npm/extract/locked-versions.spec.ts
+++ b/lib/modules/manager/npm/extract/locked-versions.spec.ts
@@ -520,11 +520,10 @@ describe('modules/manager/npm/extract/locked-versions', () => {
         packageFile: 'some-file',
       },
     ];
-    pnpm.getConstraints.mockReturnValue('>=6.0.0 >=8');
     await getLockedVersions(packageFiles);
     expect(packageFiles).toEqual([
       {
-        extractedConstraints: { pnpm: '>=6.0.0 >=8' },
+        extractedConstraints: { pnpm: '>=6.0.0' },
         deps: [
           { currentValue: '1.0.0', depName: 'a', lockedVersion: '1.0.0' },
           { currentValue: '2.0.0', depName: 'b', lockedVersion: '2.0.0' },
diff --git a/lib/modules/manager/npm/extract/locked-versions.ts b/lib/modules/manager/npm/extract/locked-versions.ts
index 42896752400b3ea94d1843d761df056b4d36eada..0515deab74de2d139ffe72c9c874b6b4665030f3 100644
--- a/lib/modules/manager/npm/extract/locked-versions.ts
+++ b/lib/modules/manager/npm/extract/locked-versions.ts
@@ -3,7 +3,7 @@ import { logger } from '../../../../logger';
 import type { PackageFile } from '../../types';
 import type { NpmManagerData } from '../types';
 import { getNpmLock } from './npm';
-import { getConstraints, getPnpmLock } from './pnpm';
+import { getPnpmLock } from './pnpm';
 import type { LockFile } from './types';
 import { getYarnLock } from './yarn';
 
@@ -106,14 +106,6 @@ export async function getLockedVersions(
         logger.trace(`Retrieving/parsing ${pnpmShrinkwrap}`);
         lockFileCache[pnpmShrinkwrap] = await getPnpmLock(pnpmShrinkwrap);
       }
-      const { lockfileVersion } = lockFileCache[pnpmShrinkwrap];
-      if (lockfileVersion) {
-        packageFile.extractedConstraints ??= {};
-        packageFile.extractedConstraints.pnpm = getConstraints(
-          lockfileVersion,
-          packageFile.extractedConstraints.pnpm
-        );
-      }
 
       for (const dep of packageFile.deps) {
         // TODO: types (#7154)
diff --git a/lib/modules/manager/npm/extract/pnpm.spec.ts b/lib/modules/manager/npm/extract/pnpm.spec.ts
index 6174595759eb5112fa6a64a7baeb527ce1af3a63..32259488514a59fa41b4e1b2473400f1f67a23de 100644
--- a/lib/modules/manager/npm/extract/pnpm.spec.ts
+++ b/lib/modules/manager/npm/extract/pnpm.spec.ts
@@ -7,7 +7,6 @@ import {
   detectPnpmWorkspaces,
   extractPnpmFilters,
   findPnpmWorkspace,
-  getConstraints,
   getPnpmLock,
 } from './pnpm';
 
@@ -231,53 +230,6 @@ describe('modules/manager/npm/extract/pnpm', () => {
     });
   });
 
-  describe('getConstraints()', () => {
-    // no constraints
-    it.each([
-      [6.0, undefined, '>=8'],
-      [5.4, undefined, '>=7 <8'],
-      [5.3, undefined, '>=6 <7'],
-      [5.2, undefined, '>=5.10.0 <6'],
-      [5.1, undefined, '>=3.5.0 <5.9.3'],
-      [5.0, undefined, '>=3 <3.5.0'],
-    ])('adds constraints for %f', (lockfileVersion, constraints, expected) => {
-      expect(getConstraints(lockfileVersion, constraints)).toBe(expected);
-    });
-
-    // constraints present
-    it.each([
-      [6.0, '>=8.2.0', '>=8.2.0'],
-      [6.0, '>=7', '>=7 >=8'],
-
-      [5.4, '^7.2.0', '^7.2.0'],
-      [5.4, '<7.2.0', '<7.2.0 >=7'],
-      [5.4, '>7.2.0', '>7.2.0 <8'],
-      [5.4, '>=6', '>=6 >=7 <8'],
-
-      [5.3, '^6.0.0', '^6.0.0'],
-      [5.3, '<6.2.0', '<6.2.0 >=6'],
-      [5.3, '>6.2.0', '>6.2.0 <7'],
-      [5.3, '>=5', '>=5 >=6 <7'],
-
-      [5.2, '5.10.0', '5.10.0'],
-      [5.2, '>5.0.0 <5.18.0', '>5.0.0 <5.18.0 >=5.10.0'],
-      [5.2, '>5.10.0', '>5.10.0 <6'],
-      [5.2, '>=5', '>=5 >=5.10.0 <6'],
-
-      [5.1, '^4.0.0', '^4.0.0'],
-      [5.1, '<4', '<4 >=3.5.0'],
-      [5.1, '>=4', '>=4 <5.9.3'],
-      [5.1, '>=3', '>=3 >=3.5.0 <5.9.3'],
-
-      [5.0, '3.1.0', '3.1.0'],
-      [5.0, '^3.0.0', '^3.0.0 <3.5.0'],
-      [5.0, '>=3', '>=3 <3.5.0'],
-      [5.0, '>=2', '>=2 >=3 <3.5.0'],
-    ])('adds constraints for %f', (lockfileVersion, constraints, expected) => {
-      expect(getConstraints(lockfileVersion, constraints)).toBe(expected);
-    });
-  });
-
   describe('.getPnpmLock()', () => {
     const readLocalFile = jest.spyOn(fs, 'readLocalFile');
 
diff --git a/lib/modules/manager/npm/extract/pnpm.ts b/lib/modules/manager/npm/extract/pnpm.ts
index 18e48b8185e1607f9d9703916193f163ddc60ab1..3ceeabc30bb001ac8cd780d6f198cf02d2881ef8 100644
--- a/lib/modules/manager/npm/extract/pnpm.ts
+++ b/lib/modules/manager/npm/extract/pnpm.ts
@@ -1,7 +1,6 @@
 import is from '@sindresorhus/is';
 import { findPackages } from 'find-packages';
 import { load } from 'js-yaml';
-import semver from 'semver';
 import upath from 'upath';
 import { GlobalConfig } from '../../../../config/global';
 import { logger } from '../../../../logger';
@@ -191,101 +190,3 @@ export async function getPnpmLock(filePath: string): Promise<LockFile> {
     return { lockedVersions: {} };
   }
 }
-
-export function getConstraints(
-  lockfileVersion: number,
-  constraints?: string
-): string {
-  let newConstraints = constraints;
-
-  // find matching lockfileVersion and use its constraints
-  // if no match found use lockfileVersion 5
-  // lockfileVersion 5 is the minimum version required to generate the pnpm-lock.yaml file
-  const { lowerBound, upperBound, lowerConstraint, upperConstraint } =
-    lockToPnpmVersionMapping.find(
-      (m) => m.lockfileVersion === lockfileVersion
-    ) ?? {
-      lockfileVersion: 5.0,
-      lowerBound: '2.24.0',
-      upperBound: '3.5.0',
-      lowerConstraint: '>=3',
-      upperConstraint: '<3.5.0',
-    };
-
-  // inorder to ensure that the constraint doesn't allow any pnpm versions that can't generate the extracted lockfileVersion
-  // compare the current constraint to the lowerBound and upperBound of the lockfileVersion
-  // if the current constraint is not comaptible, add the lowerConstraint and upperConstraint, whichever is needed
-  if (newConstraints) {
-    // if constraint satisfies versions lower than lowerBound add the lowerConstraint to narrow the range
-    if (semver.satisfies(lowerBound, newConstraints)) {
-      newConstraints += ` ${lowerConstraint}`;
-    }
-
-    // if constraint satisfies versions higher than upperBound add the upperConstraint to narrow the range
-    if (
-      upperBound &&
-      upperConstraint &&
-      semver.satisfies(upperBound, newConstraints)
-    ) {
-      newConstraints += ` ${upperConstraint}`;
-    }
-  }
-  // if no constraint is present, add the lowerConstraint and upperConstraint corresponding to the lockfileVersion
-  else {
-    newConstraints = `${lowerConstraint}${
-      upperConstraint ? ` ${upperConstraint}` : ''
-    }`;
-  }
-
-  return newConstraints;
-}
-
-/**
- pnpm lockfiles have corresponding version numbers called "lockfileVersion"
- each lockfileVersion can only be generated by a certain pnpm version ranges
- eg. lockfileVersion: 5.4 can only be generated by pnpm version >=7 && <8
- official list can be found here : https:github.com/pnpm/spec/tree/master/lockfile
- we use the mapping present below to find the compatible pnpm version range for a given lockfileVersion
-
- the various terms used in the mapping are explained below:
- lowerConstriant : lowest pnpm version that can generate the lockfileVersion
- upperConstraint : highest pnpm version that can generate the lockfileVersion
- lowerBound      : highest pnpm version that is less than the lowerConstraint
- upperBound      : lowest pnpm version that is greater than upperConstraint
-
- For handling future lockfileVersions, we need to:
- 1. add a upperBound and upperConstraint to the current lastest lockfileVersion
- 2. add an object for the new lockfileVersion with lowerBound and lowerConstraint
- */
-
-const lockToPnpmVersionMapping = [
-  { lockfileVersion: 6.0, lowerBound: '7.32.0', lowerConstraint: '>=8' },
-  {
-    lockfileVersion: 5.4,
-    lowerBound: '6.35.1',
-    upperBound: '8.0.0',
-    lowerConstraint: '>=7',
-    upperConstraint: '<8',
-  },
-  {
-    lockfileVersion: 5.3,
-    lowerBound: '5.18.10',
-    upperBound: '7.0.0',
-    lowerConstraint: '>=6',
-    upperConstraint: '<7',
-  },
-  {
-    lockfileVersion: 5.2,
-    lowerBound: '5.9.3',
-    upperBound: '5.18.10',
-    lowerConstraint: '>=5.10.0',
-    upperConstraint: '<6',
-  },
-  {
-    lockfileVersion: 5.1,
-    lowerBound: '3.4.1',
-    upperBound: '5.9.3',
-    lowerConstraint: '>=3.5.0',
-    upperConstraint: '<5.9.3',
-  },
-];
diff --git a/lib/modules/manager/npm/post-update/pnpm.spec.ts b/lib/modules/manager/npm/post-update/pnpm.spec.ts
index ed632a38c128ddede8b37bda96e7337d5430439a..5acd7a58a4a63c8934fc395fa8011af5c439cb94 100644
--- a/lib/modules/manager/npm/post-update/pnpm.spec.ts
+++ b/lib/modules/manager/npm/post-update/pnpm.spec.ts
@@ -266,4 +266,42 @@ describe('modules/manager/npm/post-update/pnpm', () => {
       },
     ]);
   });
+
+  describe('getConstraintsFromLockFile()', () => {
+    it('returns null if no lock file', async () => {
+      fs.readLocalFile.mockResolvedValueOnce(null);
+      const res = await pnpmHelper.getConstraintFromLockFile('some-file-name');
+      expect(res).toBeNull();
+    });
+
+    it('returns null when error reading lock file', async () => {
+      fs.readLocalFile.mockRejectedValueOnce(new Error('foo'));
+      const res = await pnpmHelper.getConstraintFromLockFile('some-file-name');
+      expect(res).toBeNull();
+    });
+
+    it('returns null if no lockfileVersion', async () => {
+      fs.readLocalFile.mockResolvedValueOnce('foo: bar\n');
+      const res = await pnpmHelper.getConstraintFromLockFile('some-file-name');
+      expect(res).toBeNull();
+    });
+
+    it('returns null if lockfileVersion is not a number', async () => {
+      fs.readLocalFile.mockResolvedValueOnce('lockfileVersion: foo\n');
+      const res = await pnpmHelper.getConstraintFromLockFile('some-file-name');
+      expect(res).toBeNull();
+    });
+
+    it('returns default if lockfileVersion is 1', async () => {
+      fs.readLocalFile.mockResolvedValueOnce('lockfileVersion: 1\n');
+      const res = await pnpmHelper.getConstraintFromLockFile('some-file-name');
+      expect(res).toBe('>=3 <3.5.0');
+    });
+
+    it('maps supported versions', async () => {
+      fs.readLocalFile.mockResolvedValueOnce('lockfileVersion: 5.3\n');
+      const res = await pnpmHelper.getConstraintFromLockFile('some-file-name');
+      expect(res).toBe('>=6 <7');
+    });
+  });
 });
diff --git a/lib/modules/manager/npm/post-update/pnpm.ts b/lib/modules/manager/npm/post-update/pnpm.ts
index dccc3a5c9225351b067185acc1f21e8cb893a812..a5263bdacd0cba1a9f8cd52ac563689299b20590 100644
--- a/lib/modules/manager/npm/post-update/pnpm.ts
+++ b/lib/modules/manager/npm/post-update/pnpm.ts
@@ -41,9 +41,10 @@ export async function generateLockFile(
     const pnpmToolConstraint: ToolConstraint = {
       toolName: 'pnpm',
       constraint:
-        getPnpmConstraintFromUpgrades(upgrades) ??
-        config.constraints?.pnpm ??
-        (await getPnpmConstraint(lockFileDir)),
+        getPnpmConstraintFromUpgrades(upgrades) ?? // if pnpm is being upgraded, it comes first
+        config.constraints?.pnpm ?? // from user config or extraction
+        (await getPnpmConstraintFromPackageFile(lockFileDir)) ?? // look in package.json > packageManager or engines
+        (await getConstraintFromLockFile(lockFileName)), // use lockfileVersion to find pnpm version range
     };
 
     const extraEnv: ExtraEnv = {
@@ -116,10 +117,10 @@ export async function generateLockFile(
   return { lockFile };
 }
 
-async function getPnpmConstraint(
+export async function getPnpmConstraintFromPackageFile(
   lockFileDir: string
 ): Promise<string | undefined> {
-  let result: string | undefined;
+  let constraint: string | undefined;
   const rootPackageJson = upath.join(lockFileDir, 'package.json');
   const content = await readLocalFile(rootPackageJson, 'utf8');
   if (content) {
@@ -129,27 +130,89 @@ async function getPnpmConstraint(
       const nameAndVersion = packageManager.split('@');
       const name = nameAndVersion[0];
       if (name === 'pnpm') {
-        result = nameAndVersion[1];
+        constraint = nameAndVersion[1];
       }
     } else {
       const engines = packageJson?.engines;
       if (engines) {
-        result = engines['pnpm'];
+        constraint = engines['pnpm'];
       }
     }
   }
-  if (!result) {
-    const lockFileName = upath.join(lockFileDir, 'pnpm-lock.yaml');
-    const content = await readLocalFile(lockFileName, 'utf8');
-    if (content) {
-      const pnpmLock = load(content) as PnpmLockFile;
-      if (
-        is.number(pnpmLock.lockfileVersion) &&
-        pnpmLock.lockfileVersion < 5.4
-      ) {
-        result = '<7';
-      }
+  return constraint;
+}
+
+export async function getConstraintFromLockFile(
+  lockFileName: string
+): Promise<string | null> {
+  let constraint: string | null = null;
+  try {
+    const lockfileContent = await readLocalFile(lockFileName, 'utf8');
+    if (!lockfileContent) {
+      return null;
+    }
+    const pnpmLock = load(lockfileContent) as PnpmLockFile;
+    if (!is.number(pnpmLock?.lockfileVersion)) {
+      return null;
     }
+    // find matching lockfileVersion and use its constraints
+    // if no match found use lockfileVersion 5
+    // lockfileVersion 5 is the minimum version required to generate the pnpm-lock.yaml file
+    const { lowerConstraint, upperConstraint } = lockToPnpmVersionMapping.find(
+      (m) => m.lockfileVersion === pnpmLock.lockfileVersion
+    ) ?? {
+      lockfileVersion: 5.0,
+      lowerConstraint: '>=3',
+      upperConstraint: '<3.5.0',
+    };
+    constraint = lowerConstraint;
+    if (upperConstraint) {
+      constraint += ` ${upperConstraint}`;
+    }
+  } catch (err) {
+    logger.warn({ err }, 'Error getting pnpm constraints from lock file');
   }
-  return result;
+  return constraint;
 }
+
+/**
+ pnpm lockfiles have corresponding version numbers called "lockfileVersion"
+ each lockfileVersion can only be generated by a certain pnpm version ranges
+ eg. lockfileVersion: 5.4 can only be generated by pnpm version >=7 && <8
+ official list can be found here : https://github.com/pnpm/spec/tree/master/lockfile
+ we use the mapping present below to find the compatible pnpm version range for a given lockfileVersion
+
+ the various terms used in the mapping are explained below:
+ lowerConstriant : lowest pnpm version that can generate the lockfileVersion
+ upperConstraint : highest pnpm version that can generate the lockfileVersion
+ lowerBound      : highest pnpm version that is less than the lowerConstraint
+ upperBound      : lowest pnpm version that is greater than upperConstraint
+
+ For handling future lockfileVersions, we need to:
+ 1. add a upperBound and upperConstraint to the current lastest lockfileVersion
+ 2. add an object for the new lockfileVersion with lowerBound and lowerConstraint
+ */
+
+const lockToPnpmVersionMapping = [
+  { lockfileVersion: 6.0, lowerConstraint: '>=8' },
+  {
+    lockfileVersion: 5.4,
+    lowerConstraint: '>=7',
+    upperConstraint: '<8',
+  },
+  {
+    lockfileVersion: 5.3,
+    lowerConstraint: '>=6',
+    upperConstraint: '<7',
+  },
+  {
+    lockfileVersion: 5.2,
+    lowerConstraint: '>=5.10.0',
+    upperConstraint: '<6',
+  },
+  {
+    lockfileVersion: 5.1,
+    lowerConstraint: '>=3.5.0',
+    upperConstraint: '<5.9.3',
+  },
+];