diff --git a/docs/usage/getting-started/private-packages.md b/docs/usage/getting-started/private-packages.md
index 4f0761bd1d36bfcbdc07bab4a4bce8046b17e64f..e3090fb0f6d2f3e31a03d5d0b04d7080c847324c 100644
--- a/docs/usage/getting-started/private-packages.md
+++ b/docs/usage/getting-started/private-packages.md
@@ -382,14 +382,20 @@ For example, the Renovate configuration:
 
 will update `.yarnrc.yml` as following:
 
+If no registry currently set
+
 ```yaml
 npmRegistries:
   //npm.pkg.github.com/:
     npmAuthToken: <Decrypted PAT Token>
-  //npm.pkg.github.com:
-    # this will not be overwritten and may conflict
-  https://npm.pkg.github.com/:
-    # this will not be overwritten and may conflict
+```
+
+If current registry key has protocol set:
+
+```yaml
+npmRegistries:
+  https://npm.pkg.github.com:
+    npmAuthToken: <Decrypted PAT Token>
 ```
 
 ### maven
diff --git a/lib/modules/manager/npm/post-update/index.spec.ts b/lib/modules/manager/npm/post-update/index.spec.ts
index af67dc833f217c60a6879f8b56e5cd283f93a3b6..1acaa10f78989916a1aaab9454f1770704161853 100644
--- a/lib/modules/manager/npm/post-update/index.spec.ts
+++ b/lib/modules/manager/npm/post-update/index.spec.ts
@@ -7,6 +7,7 @@ import type { FileChange } from '../../../../util/git/types';
 import type { PostUpdateConfig } from '../../types';
 import * as npm from './npm';
 import * as pnpm from './pnpm';
+import * as rules from './rules';
 import type { AdditionalPackageFiles } from './types';
 import * as yarn from './yarn';
 import {
@@ -393,11 +394,16 @@ describe('modules/manager/npm/post-update/index', () => {
     const spyNpm = jest.spyOn(npm, 'generateLockFile');
     const spyYarn = jest.spyOn(yarn, 'generateLockFile');
     const spyPnpm = jest.spyOn(pnpm, 'generateLockFile');
+    const spyProcessHostRules = jest.spyOn(rules, 'processHostRules');
 
     beforeEach(() => {
       spyNpm.mockResolvedValue({});
       spyPnpm.mockResolvedValue({});
       spyYarn.mockResolvedValue({});
+      spyProcessHostRules.mockReturnValue({
+        additionalNpmrcContent: [],
+        additionalYarnRcYml: undefined,
+      });
     });
 
     it('works', async () => {
@@ -677,5 +683,90 @@ describe('modules/manager/npm/post-update/index', () => {
         updatedArtifacts: [],
       });
     });
+
+    describe('should fuzzy merge yarn npmRegistries', () => {
+      beforeEach(() => {
+        spyProcessHostRules.mockReturnValue({
+          additionalNpmrcContent: [],
+          additionalYarnRcYml: {
+            npmRegistries: {
+              '//my-private-registry': {
+                npmAuthToken: 'xxxxxx',
+              },
+            },
+          },
+        });
+        fs.getSiblingFileName.mockReturnValue('.yarnrc.yml');
+      });
+
+      it('should fuzzy merge the yarnrc Files', async () => {
+        (yarn.fuzzyMatchAdditionalYarnrcYml as jest.Mock).mockReturnValue({
+          npmRegistries: {
+            'https://my-private-registry': { npmAuthToken: 'xxxxxx' },
+          },
+        });
+        fs.readLocalFile.mockImplementation((f): Promise<any> => {
+          if (f === '.yarnrc.yml') {
+            return Promise.resolve(
+              'npmRegistries:\n' +
+                '  https://my-private-registry:\n' +
+                '    npmAlwaysAuth: true\n',
+            );
+          }
+          return Promise.resolve(null);
+        });
+
+        spyYarn.mockResolvedValueOnce({ error: false, lockFile: '{}' });
+        await getAdditionalFiles(
+          {
+            ...updateConfig,
+            updateLockFiles: true,
+            reuseExistingBranch: true,
+          },
+          additionalFiles,
+        );
+        expect(fs.writeLocalFile).toHaveBeenCalledWith(
+          '.yarnrc.yml',
+          'npmRegistries:\n' +
+            '  https://my-private-registry:\n' +
+            '    npmAlwaysAuth: true\n' +
+            '    npmAuthToken: xxxxxx\n',
+        );
+      });
+
+      it('should warn if there is an error writing the yarnrc.yml', async () => {
+        fs.readLocalFile.mockImplementation((f): Promise<any> => {
+          if (f === '.yarnrc.yml') {
+            return Promise.resolve(
+              `yarnPath: .yarn/releases/yarn-3.0.1.cjs\na: b\n`,
+            );
+          }
+          return Promise.resolve(null);
+        });
+
+        fs.writeLocalFile.mockImplementation((f): Promise<any> => {
+          if (f === '.yarnrc.yml') {
+            throw new Error();
+          }
+          return Promise.resolve(null);
+        });
+
+        spyYarn.mockResolvedValueOnce({ error: false, lockFile: '{}' });
+
+        await getAdditionalFiles(
+          {
+            ...updateConfig,
+            updateLockFiles: true,
+            reuseExistingBranch: true,
+          },
+          additionalFiles,
+        ).catch(() => {});
+
+        expect(logger.logger.warn).toHaveBeenCalledWith(
+          expect.anything(),
+          'Error appending .yarnrc.yml content',
+        );
+      });
+    });
   });
 });
diff --git a/lib/modules/manager/npm/post-update/index.ts b/lib/modules/manager/npm/post-update/index.ts
index 20adb0c2658e5ffc9b8281240752f2701a7b9981..005400372fb5a54061ce6755142e1e89ae816058 100644
--- a/lib/modules/manager/npm/post-update/index.ts
+++ b/lib/modules/manager/npm/post-update/index.ts
@@ -563,7 +563,6 @@ export async function getAdditionalFiles(
     await updateNpmrcContent(lockFileDir, npmrcContent, additionalNpmrcContent);
     let yarnRcYmlFilename: string | undefined;
     let existingYarnrcYmlContent: string | undefined | null;
-    // istanbul ignore if: needs test
     if (additionalYarnRcYml) {
       yarnRcYmlFilename = getSiblingFileName(yarnLock, '.yarnrc.yml');
       existingYarnrcYmlContent = await readLocalFile(yarnRcYmlFilename, 'utf8');
@@ -573,10 +572,15 @@ export async function getAdditionalFiles(
           const existingYarnrRcYml = parseSingleYaml<Record<string, unknown>>(
             existingYarnrcYmlContent,
           );
+
           const updatedYarnYrcYml = deepmerge(
             existingYarnrRcYml,
-            additionalYarnRcYml,
+            yarn.fuzzyMatchAdditionalYarnrcYml(
+              additionalYarnRcYml,
+              existingYarnrRcYml,
+            ),
           );
+
           await writeLocalFile(yarnRcYmlFilename, dump(updatedYarnYrcYml));
           logger.debug('Added authentication to .yarnrc.yml');
         } catch (err) {
diff --git a/lib/modules/manager/npm/post-update/yarn.spec.ts b/lib/modules/manager/npm/post-update/yarn.spec.ts
index f832ca6570ae831d2d047daa78401be9510cb5e3..791b648c3c0fe8f76a4c6825db42c11c64ad6f26 100644
--- a/lib/modules/manager/npm/post-update/yarn.spec.ts
+++ b/lib/modules/manager/npm/post-update/yarn.spec.ts
@@ -726,4 +726,55 @@ describe('modules/manager/npm/post-update/yarn', () => {
       expect(Fixtures.toJSON()['/tmp/renovate/.yarnrc']).toBe('\n\n');
     });
   });
+
+  describe('fuzzyMatchAdditionalYarnrcYml()', () => {
+    it.each`
+      additionalRegistry            | existingRegistry                    | expectedRegistry
+      ${['//my-private-registry']}  | ${['//my-private-registry']}        | ${['//my-private-registry']}
+      ${[]}                         | ${['//my-private-registry']}        | ${[]}
+      ${[]}                         | ${[]}                               | ${[]}
+      ${null}                       | ${null}                             | ${[]}
+      ${['//my-private-registry']}  | ${[]}                               | ${['//my-private-registry']}
+      ${['//my-private-registry']}  | ${['https://my-private-registry']}  | ${['https://my-private-registry']}
+      ${['//my-private-registry']}  | ${['http://my-private-registry']}   | ${['http://my-private-registry']}
+      ${['//my-private-registry']}  | ${['http://my-private-registry/']}  | ${['http://my-private-registry/']}
+      ${['//my-private-registry']}  | ${['https://my-private-registry/']} | ${['https://my-private-registry/']}
+      ${['//my-private-registry']}  | ${['//my-private-registry/']}       | ${['//my-private-registry/']}
+      ${['//my-private-registry/']} | ${['//my-private-registry/']}       | ${['//my-private-registry/']}
+      ${['//my-private-registry/']} | ${['//my-private-registry']}        | ${['//my-private-registry']}
+    `(
+      'should return $expectedRegistry when parsing $additionalRegistry against local $existingRegistry',
+      ({
+        additionalRegistry,
+        existingRegistry,
+        expectedRegistry,
+      }: Record<
+        'additionalRegistry' | 'existingRegistry' | 'expectedRegistry',
+        string[]
+      >) => {
+        expect(
+          yarnHelper.fuzzyMatchAdditionalYarnrcYml(
+            {
+              npmRegistries: additionalRegistry?.reduce(
+                (acc, cur) => ({
+                  ...acc,
+                  [cur]: { npmAuthToken: 'xxxxxx' },
+                }),
+                {},
+              ),
+            },
+            {
+              npmRegistries: existingRegistry?.reduce(
+                (acc, cur) => ({
+                  ...acc,
+                  [cur]: { npmAuthToken: 'xxxxxx' },
+                }),
+                {},
+              ),
+            },
+          ).npmRegistries,
+        ).toContainAllKeys(expectedRegistry);
+      },
+    );
+  });
 });
diff --git a/lib/modules/manager/npm/post-update/yarn.ts b/lib/modules/manager/npm/post-update/yarn.ts
index 92488dd4563fc7d1871757dc523d25e6d5b27908..eae353681990d584a793ea9fe19740b703098d6c 100644
--- a/lib/modules/manager/npm/post-update/yarn.ts
+++ b/lib/modules/manager/npm/post-update/yarn.ts
@@ -315,3 +315,24 @@ export async function generateLockFile(
   }
   return { lockFile };
 }
+
+export function fuzzyMatchAdditionalYarnrcYml<
+  T extends { npmRegistries?: Record<string, unknown> },
+>(additionalYarnRcYml: T, existingYarnrRcYml: T): T {
+  const keys = new Map(
+    Object.keys(existingYarnrRcYml.npmRegistries ?? {}).map((x) => [
+      x.replace(/\/$/, '').replace(/^https?:/, ''),
+      x,
+    ]),
+  );
+
+  return {
+    ...additionalYarnRcYml,
+    npmRegistries: Object.entries(additionalYarnRcYml.npmRegistries ?? {})
+      .map(([k, v]) => {
+        const key = keys.get(k.replace(/\/$/, '')) ?? k;
+        return { [key]: v };
+      })
+      .reduce((acc, cur) => ({ ...acc, ...cur }), {}),
+  };
+}