diff --git a/lib/modules/manager/pub/artifacts.spec.ts b/lib/modules/manager/pub/artifacts.spec.ts
index 2ae1fb8bb7803fa5f6c27c131a312c2d8c9870fa..c7b8aaf9037d8012c0f0dfc4e02086704083c9bf 100644
--- a/lib/modules/manager/pub/artifacts.spec.ts
+++ b/lib/modules/manager/pub/artifacts.spec.ts
@@ -41,7 +41,6 @@ const updateArtifact: UpdateArtifact = {
 describe('modules/manager/pub/artifacts', () => {
   beforeEach(() => {
     jest.resetAllMocks();
-    jest.resetModules();
 
     env.getChildProcessEnv.mockReturnValue(envMock.basic);
     GlobalConfig.set(adminConfig);
diff --git a/lib/modules/manager/pub/artifacts.ts b/lib/modules/manager/pub/artifacts.ts
index 16b4de4b22fb8b288d7b8daf20d3f98d2370e9d9..613cd364ce95932ac1e039807c6d165201d20e3e 100644
--- a/lib/modules/manager/pub/artifacts.ts
+++ b/lib/modules/manager/pub/artifacts.ts
@@ -9,19 +9,8 @@ import {
   readLocalFile,
   writeLocalFile,
 } from '../../../util/fs';
-import { regEx } from '../../../util/regex';
 import type { UpdateArtifact, UpdateArtifactsResult } from '../types';
-
-function getFlutterConstraint(lockFileContent: string): string | undefined {
-  return regEx(/^\tflutter: ['"](?<flutterVersion>.*)['"]$/m).exec(
-    lockFileContent
-  )?.groups?.flutterVersion;
-}
-
-function getDartConstraint(lockFileContent: string): string | undefined {
-  return regEx(/^\tdart: ['"](?<dartVersion>.*)['"]$/m).exec(lockFileContent)
-    ?.groups?.dartVersion;
-}
+import { parsePubspecLock } from './utils';
 
 export async function updateArtifacts({
   packageFileName,
@@ -63,9 +52,12 @@ export async function updateArtifacts({
       );
     }
 
-    const constraint = isFlutter
-      ? config.constraints?.flutter ?? getFlutterConstraint(oldLockFileContent)
-      : config.constraints?.dart ?? getDartConstraint(oldLockFileContent);
+    let constraint = config.constraints?.[toolName];
+    if (!constraint) {
+      const pubspecLock = parsePubspecLock(lockFileName, oldLockFileContent);
+      constraint = pubspecLock?.sdks[toolName];
+    }
+
     const execOptions: ExecOptions = {
       cwdFile: packageFileName,
       docker: {},
diff --git a/lib/modules/manager/pub/schema.ts b/lib/modules/manager/pub/schema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dbf72be5c7fd3f23792f0947300b7a3cad9b5f64
--- /dev/null
+++ b/lib/modules/manager/pub/schema.ts
@@ -0,0 +1,13 @@
+import { z } from 'zod';
+import { Yaml } from '../../../util/schema-utils';
+
+export const PubspecLockSchema = z.object({
+  sdks: z.object({
+    dart: z.string(),
+    flutter: z.string().optional(),
+  }),
+});
+
+export type PubspecLockSchema = z.infer<typeof PubspecLockSchema>;
+
+export const PubspecLockYaml = Yaml.pipe(PubspecLockSchema);
diff --git a/lib/modules/manager/pub/utils.spec.ts b/lib/modules/manager/pub/utils.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c236d4c0bed7749ee07f3725784289c0e1ee8116
--- /dev/null
+++ b/lib/modules/manager/pub/utils.spec.ts
@@ -0,0 +1,30 @@
+import { codeBlock } from 'common-tags';
+import { parsePubspecLock } from './utils';
+
+describe('modules/manager/pub/utils', () => {
+  describe('parsePubspeckLock', () => {
+    const fileName = 'pubspec.lock';
+
+    it('load and parse successfully', () => {
+      const pubspecLock = codeBlock`
+        sdks:
+          dart: ">=3.0.0 <4.0.0"
+          flutter: ">=3.10.0"
+      `;
+      const actual = parsePubspecLock(fileName, pubspecLock);
+      expect(actual).toMatchObject({
+        sdks: { dart: '>=3.0.0 <4.0.0', flutter: '>=3.10.0' },
+      });
+    });
+
+    it('invalid yaml', () => {
+      const actual = parsePubspecLock(fileName, 'clearly-invalid');
+      expect(actual).toBeNull();
+    });
+
+    it('invalid schema', () => {
+      const actual = parsePubspecLock(fileName, 'clearly:\n\tinvalid: lock');
+      expect(actual).toBeNull();
+    });
+  });
+});
diff --git a/lib/modules/manager/pub/utils.ts b/lib/modules/manager/pub/utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7aa7f05e0e4c5f71fa08afb603eee72d92a166fd
--- /dev/null
+++ b/lib/modules/manager/pub/utils.ts
@@ -0,0 +1,18 @@
+import { logger } from '../../../logger';
+import { PubspecLockSchema, PubspecLockYaml } from './schema';
+
+export function parsePubspecLock(
+  fileName: string,
+  fileContent: string
+): PubspecLockSchema | null {
+  const res = PubspecLockYaml.safeParse(fileContent);
+  if (res.success) {
+    return res.data;
+  } else {
+    logger.debug(
+      { err: res.error, fileName },
+      `Error parsing pubspec lockfile.`
+    );
+  }
+  return null;
+}
diff --git a/lib/util/schema-utils.spec.ts b/lib/util/schema-utils.spec.ts
index 9be7ac651c4489a43f87f2c15c90aca5c43e294a..c194236ce6c8bd961f6e6607d1e3056760108bf9 100644
--- a/lib/util/schema-utils.spec.ts
+++ b/lib/util/schema-utils.spec.ts
@@ -6,6 +6,7 @@ import {
   LooseRecord,
   Url,
   UtcDate,
+  Yaml,
 } from './schema-utils';
 
 describe('util/schema-utils', () => {
@@ -295,4 +296,48 @@ describe('util/schema-utils', () => {
       expect(() => Url.parse(urlStr)).toThrow('Invalid URL');
     });
   });
+
+  describe('Yaml', () => {
+    const Schema = Yaml.pipe(
+      z.object({ foo: z.array(z.object({ bar: z.literal('baz') })) })
+    );
+
+    it('parses valid yaml', () => {
+      expect(Schema.parse('foo:\n- bar: baz')).toEqual({
+        foo: [{ bar: 'baz' }],
+      });
+    });
+
+    it('throws error for non-string', () => {
+      expect(Schema.safeParse(42)).toMatchObject({
+        error: {
+          issues: [
+            {
+              message: 'Expected string, received number',
+              code: 'invalid_type',
+              expected: 'string',
+              received: 'number',
+              path: [],
+            },
+          ],
+        },
+        success: false,
+      });
+    });
+
+    it('throws error for invalid yaml', () => {
+      expect(Schema.safeParse('clearly: "invalid" "yaml"')).toMatchObject({
+        error: {
+          issues: [
+            {
+              message: 'Invalid YAML',
+              code: 'custom',
+              path: [],
+            },
+          ],
+        },
+        success: false,
+      });
+    });
+  });
 });
diff --git a/lib/util/schema-utils.ts b/lib/util/schema-utils.ts
index 0caa342e39164329121da32abf098b993f9a4a1c..e200a04bd10e8295c8fdcaa2e0f538f09c1c3bcf 100644
--- a/lib/util/schema-utils.ts
+++ b/lib/util/schema-utils.ts
@@ -1,3 +1,4 @@
+import { load } from 'js-yaml';
 import JSON5 from 'json5';
 import { DateTime } from 'luxon';
 import type { JsonValue } from 'type-fest';
@@ -232,3 +233,12 @@ export const Url = z.string().transform((str, ctx): URL => {
     return z.NEVER;
   }
 });
+
+export const Yaml = z.string().transform((str, ctx): JsonValue => {
+  try {
+    return load(str, { json: true }) as JsonValue;
+  } catch (e) {
+    ctx.addIssue({ code: 'custom', message: 'Invalid YAML' });
+    return z.NEVER;
+  }
+});