diff --git a/lib/modules/manager/cargo/artifacts.spec.ts b/lib/modules/manager/cargo/artifacts.spec.ts
index ddae974b6549bb533855487735eda9ce0c1c671b..cf196a4081418dbd41513d32569af50ba926813d 100644
--- a/lib/modules/manager/cargo/artifacts.spec.ts
+++ b/lib/modules/manager/cargo/artifacts.spec.ts
@@ -7,7 +7,7 @@ import {
 } from '../../../../test/exec-util';
 import { env, fs, git, mocked } from '../../../../test/util';
 import { GlobalConfig } from '../../../config/global';
-import type { RepoGlobalConfig } from '../../../config/types';
+import type { RepoGlobalConfig, UpdateType } from '../../../config/types';
 import * as docker from '../../../util/exec/docker';
 import { ExecError } from '../../../util/exec/exec-error';
 import * as _hostRules from '../../../util/host-rules';
@@ -132,6 +132,7 @@ describe('modules/manager/cargo/artifacts', () => {
         packageName: 'dep1',
         lockedVersion: '1.0.0',
         newVersion: '1.0.1',
+        updateType: 'lockfileUpdate' satisfies UpdateType as UpdateType,
       },
     ];
     expect(
@@ -290,18 +291,21 @@ describe('modules/manager/cargo/artifacts', () => {
         packageName: 'dep1',
         lockedVersion: '1.0.0',
         newVersion: '1.0.1',
+        updateType: 'lockfileUpdate' satisfies UpdateType as UpdateType,
       },
       {
         depName: 'dep2',
         packageName: 'dep2',
         lockedVersion: '1.0.0',
         newVersion: '1.0.2',
+        updateType: 'lockfileUpdate' satisfies UpdateType as UpdateType,
       },
       {
         depName: 'dep3',
         packageName: 'dep3',
         lockedVersion: '1.0.0',
         newVersion: '1.0.3',
+        updateType: 'lockfileUpdate' satisfies UpdateType as UpdateType,
       },
     ];
 
@@ -328,6 +332,62 @@ describe('modules/manager/cargo/artifacts', () => {
     ]);
   });
 
+  it('runs cargo update precise only for lockfile update', async () => {
+    fs.statLocalFile.mockResolvedValueOnce({ name: 'Cargo.lock' } as any);
+    fs.findLocalSiblingOrParent.mockResolvedValueOnce('Cargo.lock');
+    git.getFile.mockResolvedValueOnce('Old Cargo.lock');
+    const execSnapshots = mockExecAll();
+    fs.findLocalSiblingOrParent.mockResolvedValueOnce('Cargo.lock');
+    fs.readLocalFile.mockResolvedValueOnce('New Cargo.lock');
+    const updatedDeps = [
+      {
+        depName: 'dep1',
+        packageName: 'dep1',
+        updateType: 'minor' satisfies UpdateType as UpdateType,
+        lockedVersion: '1.0.0',
+        newVersion: '1.0.1',
+      },
+      {
+        depName: 'dep2',
+        packageName: 'dep2',
+        updateType: 'minor' satisfies UpdateType as UpdateType,
+        lockedVersion: '1.0.0',
+        newVersion: '1.0.2',
+      },
+      {
+        depName: 'dep3',
+        packageName: 'dep3',
+        updateType: 'lockfileUpdate' satisfies UpdateType as UpdateType,
+        lockedVersion: '1.0.0',
+        newVersion: '1.0.3',
+      },
+    ];
+    expect(
+      await cargo.updateArtifacts({
+        packageFileName: 'Cargo.toml',
+        updatedDeps,
+        newPackageFileContent: '{}',
+        config,
+      }),
+    ).toEqual([
+      { file: { contents: undefined, path: 'Cargo.lock', type: 'addition' } },
+    ]);
+    expect(execSnapshots).toMatchObject([
+      {
+        cmd:
+          'cargo update --config net.git-fetch-with-cli=true' +
+          ' --manifest-path Cargo.toml' +
+          ' --workspace',
+      },
+      {
+        cmd:
+          'cargo update --config net.git-fetch-with-cli=true' +
+          ' --manifest-path Cargo.toml' +
+          ' --package dep3@1.0.0 --precise 1.0.3',
+      },
+    ]);
+  });
+
   it('returns updated Cargo.lock when there are no more dependencies to update', async () => {
     fs.findLocalSiblingOrParent.mockResolvedValueOnce('Cargo.lock');
     fs.readLocalFile.mockResolvedValueOnce('New Cargo.lock');
diff --git a/lib/modules/manager/cargo/artifacts.ts b/lib/modules/manager/cargo/artifacts.ts
index 8ac570605d200842d097f0c2d991e76286549cb9..24c8c58e2d267f3611eea2bb8da06ecfa03e4a87 100644
--- a/lib/modules/manager/cargo/artifacts.ts
+++ b/lib/modules/manager/cargo/artifacts.ts
@@ -54,6 +54,10 @@ async function cargoUpdatePrecise(
   // Update individual dependencies to their `newVersion`. Necessary when
   // using the `update-lockfile` rangeStrategy which doesn't touch Cargo.toml.
   for (const dep of updatedDeps) {
+    // Cargo update should already have handled any non-lockfile updates
+    if (dep.updateType !== 'lockfileUpdate') {
+      continue;
+    }
     cmds.push(
       `cargo update --config net.git-fetch-with-cli=true` +
         ` --manifest-path ${quote(manifestPath)}` +
@@ -144,7 +148,6 @@ async function updateArtifactsImpl(
           config.constraints?.rust,
         );
       } else {
-        // If all dependencies have locked versions then update them precisely.
         await cargoUpdatePrecise(
           packageFileName,
           updatedDeps,