diff --git a/docs/usage/bazel.md b/docs/usage/bazel.md
index 8eec08f4e1de588bfd49b3db28b14e4aafede5d6..9aa7c6d9f0b59b4e15aab24c6f36b743c09b8c0b 100644
--- a/docs/usage/bazel.md
+++ b/docs/usage/bazel.md
@@ -154,14 +154,18 @@ Renovate ignores [`multiple_version_override`](https://bazel.build/rules/lib/glo
 
 ## Legacy `WORKSPACE` files
 
-Renovate extracts dependencies from:
+Renovate extracts dependencies from the following repository rules:
 
 - `container_pull`
 - `oci_pull`
 - `git_repository`
 - `go_repository`
 - `maven_install`
-- `http_archive` or `http_file` declarations
+- `http_archive`
+- `http_file`
+
+It also recognizes when these repository rule names are prefixed with an
+underscore. For example, `_http_archive` is treated the same as `http_archive`.
 
 ### `git_repository`
 
diff --git a/lib/modules/manager/bazel/__fixtures__/WORKSPACE2 b/lib/modules/manager/bazel/__fixtures__/WORKSPACE2
index 0d82bf137895532af90ed6bbe0d8d668d9756dea..40417b4837d04e9b714598b960c4481f0b4fc847 100644
--- a/lib/modules/manager/bazel/__fixtures__/WORKSPACE2
+++ b/lib/modules/manager/bazel/__fixtures__/WORKSPACE2
@@ -1,14 +1,14 @@
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:http.bzl", _http_archive = "http_archive")
 load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
 
-http_archive(
+_http_archive(
     name = "GBDeviceInfo",
     url = "https://github.com/lmirosevic/GBDeviceInfo/archive/6.3.0.tar.gz",
     sha256 = "d7666275dff039407ea467c3083b83e24934101777c8b55b6b1b3b7e9a9e220b",
     strip_prefix = "GBDeviceInfo-6.3.0/GBDeviceInfo"
 )
 
-http_archive(
+_http_archive(
     name = "com_github_nelhage_rules_boost",
     url = "https://github.com/nelhage/rules_boost/archive/135d46b4c9423ee7d494c78a21ff621bc73c12f3.tar.gz",
     sha256 = "3651f5dda0f7296e4cecafacc7f9d1f274be0fd64e30bebd74e28ffba28fe77f",
@@ -17,14 +17,14 @@ http_archive(
 load("@com_github_nelhage_rules_boost//:boost/boost.bzl", "boost_deps")
 boost_deps()
 
-http_archive(
+_http_archive(
     name = "GBDeviceInfo-zip",
     url = "https://github.com/lmirosevic/GBDeviceInfo/archive/6.3.0.zip",
     sha256 = "4ef4320c4880fd64cfb7f42132f4b02fa626bccf1ba3e1a71dfbfcb50735f141",
     strip_prefix = "GBDeviceInfo-6.3.0/GBDeviceInfo"
 )
 
-http_archive(
+_http_archive(
     name = "com_github_nelhage_rules_boost-zip",
     url = "https://github.com/nelhage/rules_boost/archive/135d46b4c9423ee7d494c78a21ff621bc73c12f3.zip",
     sha256 = "de8aac034cabe4a9ba5f7a33b9523862bf76c245a6c554c0e737f591bb7c7aeb",
@@ -32,7 +32,7 @@ http_archive(
 )
 
 maybe(
-  http_archive,
+  _http_archive,
   name = "io_bazel_rules_go",
   sha256 = "2b1641428dff9018f9e85c0384f03ec6c10660d935b750e3fa1492a281a53b0f",
   url = "https://github.com/bazelbuild/rules_go/releases/download/v0.29.0/rules_go-v0.29.0.zip",
diff --git a/lib/modules/manager/bazel/artifacts.spec.ts b/lib/modules/manager/bazel/artifacts.spec.ts
index 71ab62644fd4d4ad3b8e766ef9e1f3ce75619449..e70c4f0499b68fcfd3ced96c2ecfa6998547f2de 100644
--- a/lib/modules/manager/bazel/artifacts.spec.ts
+++ b/lib/modules/manager/bazel/artifacts.spec.ts
@@ -276,6 +276,61 @@ describe('modules/manager/bazel/artifacts', () => {
     expect(res).toBeNull();
   });
 
+  it('errors for _http_archive without urls', async () => {
+    const input = codeBlock`
+      _http_archive(
+        name = "bazel_skylib",
+        sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f",
+        strip_prefix = "bazel-skylib-0.5.0",
+      )
+    `;
+
+    const upgrade = {
+      depName: 'bazel_skylib',
+      depType: 'http_archive',
+      repo: 'bazelbuild/bazel-skylib',
+      managerData: { idx: 0 },
+      currentValue: '0.5.0',
+      newValue: '0.6.2',
+    };
+    const res = await updateArtifacts(
+      partial<UpdateArtifact>({
+        packageFileName: 'WORKSPACE',
+        updatedDeps: [upgrade],
+        newPackageFileContent: input,
+      })
+    );
+    expect(res).toBeNull();
+  });
+
+  it('errors for maybe(_http_archive) without urls', async () => {
+    const input = codeBlock`
+      maybe(
+        _http_archive,
+        name = "bazel_skylib",
+        sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f",
+        strip_prefix = "bazel-skylib-0.5.0",
+      )
+    `;
+
+    const upgrade = {
+      depName: 'bazel_skylib',
+      depType: 'http_archive',
+      repo: 'bazelbuild/bazel-skylib',
+      managerData: { idx: 0 },
+      currentValue: '0.5.0',
+      newValue: '0.6.2',
+    };
+    const res = await updateArtifacts(
+      partial<UpdateArtifact>({
+        packageFileName: 'WORKSPACE',
+        updatedDeps: [upgrade],
+        newPackageFileContent: input,
+      })
+    );
+    expect(res).toBeNull();
+  });
+
   it('updates http_archive with urls array', async () => {
     const inputHash =
       'b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f';
@@ -410,6 +465,140 @@ describe('modules/manager/bazel/artifacts', () => {
     ]);
   });
 
+  it('updates _http_archive with urls array', async () => {
+    const inputHash =
+      'b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f';
+    const input = codeBlock`
+      _http_archive(
+        name = "bazel_skylib",
+        sha256 = "${inputHash}",
+        strip_prefix = "bazel-skylib-0.5.0",
+        urls = [
+          "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
+          "https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
+        ],
+      )
+    `;
+
+    const currentValue = '0.5.0';
+    const newValue = '0.6.2';
+    const upgrade = {
+      depName: 'bazel_skylib',
+      depType: 'http_archive',
+      repo: 'bazelbuild/bazel-skylib',
+      managerData: { idx: 0 },
+      currentValue,
+      newValue,
+    };
+
+    const tarContent = Buffer.from('foo');
+    const outputHash = crypto
+      .createHash('sha256')
+      .update(tarContent)
+      .digest('hex');
+
+    const output = input
+      .replace(currentValue, newValue)
+      .replace(currentValue, newValue)
+      .replace(currentValue, newValue)
+      .replace(inputHash, outputHash);
+
+    httpMock
+      .scope('https://github.com')
+      .get('/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz')
+      .reply(200, tarContent);
+
+    httpMock
+      .scope('https://mirror.bazel.build')
+      .get('/github.com/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz')
+      .reply(200, tarContent);
+
+    const res = await updateArtifacts(
+      partial<UpdateArtifact>({
+        packageFileName: 'WORKSPACE',
+        updatedDeps: [upgrade],
+        newPackageFileContent: input,
+      })
+    );
+
+    expect(res).toEqual([
+      {
+        file: {
+          contents: output,
+          path: 'WORKSPACE',
+          type: 'addition',
+        },
+      },
+    ]);
+  });
+
+  it('updates maybe(_http_archive) with urls array', async () => {
+    const inputHash =
+      'b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f';
+    const input = codeBlock`
+      maybe(
+        _http_archive,
+        name = "bazel_skylib",
+        sha256 = "${inputHash}",
+        strip_prefix = "bazel-skylib-0.5.0",
+        urls = [
+            "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
+            "https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
+        ],
+      )
+    `;
+
+    const currentValue = '0.5.0';
+    const newValue = '0.6.2';
+    const upgrade = {
+      depName: 'bazel_skylib',
+      depType: 'http_archive',
+      repo: 'bazelbuild/bazel-skylib',
+      managerData: { idx: 0 },
+      currentValue,
+      newValue,
+    };
+
+    const tarContent = Buffer.from('foo');
+    const outputHash = crypto
+      .createHash('sha256')
+      .update(tarContent)
+      .digest('hex');
+
+    const output = input
+      .replace(currentValue, newValue)
+      .replace(currentValue, newValue)
+      .replace(currentValue, newValue)
+      .replace(inputHash, outputHash);
+
+    httpMock
+      .scope('https://github.com')
+      .get('/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz')
+      .reply(200, tarContent);
+    httpMock
+      .scope('https://mirror.bazel.build')
+      .get('/github.com/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz')
+      .reply(200, tarContent);
+
+    const res = await updateArtifacts(
+      partial<UpdateArtifact>({
+        packageFileName: 'WORKSPACE',
+        updatedDeps: [upgrade],
+        newPackageFileContent: input,
+      })
+    );
+
+    expect(res).toEqual([
+      {
+        file: {
+          contents: output,
+          path: 'WORKSPACE',
+          type: 'addition',
+        },
+      },
+    ]);
+  });
+
   it('updates one http_archive alongside others', async () => {
     const inputHash =
       '5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064';
diff --git a/lib/modules/manager/bazel/extract.ts b/lib/modules/manager/bazel/extract.ts
index 3eee87916a904ad39d7ca544bf78da49e54d1fb3..78349672af895f3493a2c5099e8fd3b6f9d47f8d 100644
--- a/lib/modules/manager/bazel/extract.ts
+++ b/lib/modules/manager/bazel/extract.ts
@@ -1,6 +1,10 @@
 import type { PackageDependency, PackageFileContent } from '../types';
 import { parse } from './parser';
 import { extractDepsFromFragment } from './rules';
+import { dockerRules } from './rules/docker';
+import { gitRules } from './rules/git';
+import { goRules } from './rules/go';
+import { ociRules } from './rules/oci';
 import type { RecordFragment } from './types';
 
 export function extractPackageFile(
@@ -19,15 +23,11 @@ export function extractPackageFile(
     for (const dep of extractDepsFromFragment(fragment)) {
       dep.managerData = { idx };
 
-      // Selectively provide `replaceString` in order
-      // to auto-replace functionality work correctly.
+      // Selectively provide `replaceString` in order to make auto-replace
+      // functionality work correctly.
+      const rules = [...dockerRules, ...ociRules, ...gitRules, ...goRules];
       const replaceString = fragment.value;
-      if (
-        replaceString.startsWith('container_pull') ||
-        replaceString.startsWith('oci_pull') ||
-        replaceString.startsWith('git_repository') ||
-        replaceString.startsWith('go_repository')
-      ) {
+      if (rules.some((rule) => replaceString.startsWith(rule))) {
         if (dep.currentValue && dep.currentDigest) {
           dep.replaceString = replaceString;
         }
diff --git a/lib/modules/manager/bazel/parser.spec.ts b/lib/modules/manager/bazel/parser.spec.ts
index 7bdccab9167eb3dcedcf9956925b4150d39ef738..2b56cad88f0e0b09b8a60db212a96fd85a08f307 100644
--- a/lib/modules/manager/bazel/parser.spec.ts
+++ b/lib/modules/manager/bazel/parser.spec.ts
@@ -7,6 +7,8 @@ describe('modules/manager/bazel/parser', () => {
     const input = codeBlock`
       go_repository(name = "foo")
       maybe(go_repository, name = "bar", deps = ["baz", "qux"])
+      _go_repository(name = "quux")
+      maybe(_go_repository, name = "corge", deps = ["grault", "garply"])
     `;
 
     const res = parse(input);
@@ -39,10 +41,40 @@ describe('modules/manager/bazel/parser', () => {
           },
         },
       },
+      {
+        type: 'record',
+        value: '_go_repository(name = "quux")',
+        offset: 86,
+        children: {
+          rule: { type: 'string', value: '_go_repository', offset: 86 },
+          name: { type: 'string', value: 'quux', offset: 109 },
+        },
+      },
+      {
+        type: 'record',
+        value:
+          'maybe(_go_repository, name = "corge", deps = ["grault", "garply"])',
+        offset: 116,
+        children: {
+          rule: { type: 'string', value: '_go_repository', offset: 122 },
+          name: { type: 'string', value: 'corge', offset: 146 },
+          deps: {
+            type: 'array',
+            value: '["grault", "garply"]',
+            offset: 161,
+            children: [
+              { type: 'string', value: 'grault', offset: 163 },
+              { type: 'string', value: 'garply', offset: 173 },
+            ],
+          },
+        },
+      },
     ]);
     expect(res?.map(extract)).toMatchObject([
       { rule: 'go_repository', name: 'foo' },
       { rule: 'go_repository', name: 'bar', deps: ['baz', 'qux'] },
+      { rule: '_go_repository', name: 'quux' },
+      { rule: '_go_repository', name: 'corge', deps: ['grault', 'garply'] },
     ]);
   });
 
diff --git a/lib/modules/manager/bazel/parser.ts b/lib/modules/manager/bazel/parser.ts
index 42905bb072490db3260bcac8145623e53df7663b..996a05c65e1cfe84d5cfd3ce50cac0335b4e3e3a 100644
--- a/lib/modules/manager/bazel/parser.ts
+++ b/lib/modules/manager/bazel/parser.ts
@@ -261,7 +261,7 @@ function ruleNameHandler(ctx: Ctx, { value, offset }: lexer.Token): Ctx {
 /**
  * Matches regular rules:
  * - `git_repository(...)`
- * - `go_repository(...)`
+ * - `_go_repository(...)`
  */
 const regularRule = q
   .sym<Ctx>(supportedRulesRegex, (ctx, token) =>
@@ -272,7 +272,7 @@ const regularRule = q
 /**
  * Matches "maybe"-form rules:
  * - `maybe(git_repository, ...)`
- * - `maybe(go_repository, ...)`
+ * - `maybe(_go_repository, ...)`
  */
 const maybeRule = q
   .sym<Ctx>('maybe', recordStartHandler)
diff --git a/lib/modules/manager/bazel/rules/docker.ts b/lib/modules/manager/bazel/rules/docker.ts
index 4ccc83d62694c69d1e1312cc988d7068d5720147..6d75313c5ae35e5a5f194106ea8b0300e7f8c68e 100644
--- a/lib/modules/manager/bazel/rules/docker.ts
+++ b/lib/modules/manager/bazel/rules/docker.ts
@@ -3,7 +3,7 @@ import { DockerDatasource } from '../../../datasource/docker';
 import { id as dockerVersioning } from '../../../versioning/docker';
 import type { PackageDependency } from '../../types';
 
-export const dockerRules = ['container_pull'] as const;
+export const dockerRules = ['container_pull', '_container_pull'] as const;
 
 export const DockerTarget = z
   .object({
diff --git a/lib/modules/manager/bazel/rules/git.ts b/lib/modules/manager/bazel/rules/git.ts
index 1cafda692c18857ab20abe91d325c38e62319f56..d63f5956b761ed615a1d7af55cd4f21aaad43486 100644
--- a/lib/modules/manager/bazel/rules/git.ts
+++ b/lib/modules/manager/bazel/rules/git.ts
@@ -17,7 +17,7 @@ function githubPackageName(input: string): string | undefined {
   return parseGithubUrl(input)?.match(githubUrlRegex)?.groups?.packageName;
 }
 
-export const gitRules = ['git_repository'] as const;
+export const gitRules = ['git_repository', '_git_repository'] as const;
 
 export const GitTarget = z
   .object({
diff --git a/lib/modules/manager/bazel/rules/go.ts b/lib/modules/manager/bazel/rules/go.ts
index 5bbf35302e2896163ceab2391f876978298dd69f..1512001e04a5419f17df3620f28040a1a5f1c8a8 100644
--- a/lib/modules/manager/bazel/rules/go.ts
+++ b/lib/modules/manager/bazel/rules/go.ts
@@ -3,7 +3,7 @@ import { regEx } from '../../../../util/regex';
 import { GoDatasource } from '../../../datasource/go';
 import type { PackageDependency } from '../../types';
 
-export const goRules = ['go_repository'] as const;
+export const goRules = ['go_repository', '_go_repository'] as const;
 
 export const GoTarget = z
   .object({
diff --git a/lib/modules/manager/bazel/rules/http.ts b/lib/modules/manager/bazel/rules/http.ts
index 16c87fe5a6fc3108a7c11e73538a53db6f95c141..fe4b166172d22b151414c48f924020769e3f07e8 100644
--- a/lib/modules/manager/bazel/rules/http.ts
+++ b/lib/modules/manager/bazel/rules/http.ts
@@ -119,7 +119,12 @@ export function parseArchiveUrl(
   return null;
 }
 
-export const httpRules = ['http_archive', 'http_file'] as const;
+export const httpRules = [
+  'http_archive',
+  '_http_archive',
+  'http_file',
+  '_http_file',
+] as const;
 
 export const HttpTarget = z
   .object({
diff --git a/lib/modules/manager/bazel/rules/index.ts b/lib/modules/manager/bazel/rules/index.ts
index ca016579171f61054c9de00471721ae6a894841c..30d275fe0f0fc8b3ed5a81bf255da8e5da7ab6a3 100644
--- a/lib/modules/manager/bazel/rules/index.ts
+++ b/lib/modules/manager/bazel/rules/index.ts
@@ -30,7 +30,7 @@ const supportedRules = [
   ...httpRules,
   ...mavenRules,
 ];
-export const supportedRulesRegex = regEx(`^${supportedRules.join('|')}$`);
+export const supportedRulesRegex = regEx(`^(?:${supportedRules.join('|')})$`);
 
 export function extractDepsFromFragmentData(
   fragmentData: FragmentData
diff --git a/lib/modules/manager/bazel/rules/maven.ts b/lib/modules/manager/bazel/rules/maven.ts
index 5107ea1ad499051d342f88e8b132f194a719b9ee..7622bb7b374ea0c9681954c2eb23f87366fffb27 100644
--- a/lib/modules/manager/bazel/rules/maven.ts
+++ b/lib/modules/manager/bazel/rules/maven.ts
@@ -4,7 +4,7 @@ import { MavenDatasource } from '../../../datasource/maven';
 import { id as versioning } from '../../../versioning/gradle';
 import type { PackageDependency } from '../../types';
 
-export const mavenRules = ['maven_install'] as const;
+export const mavenRules = ['maven_install', '_maven_install'] as const;
 
 const ArtifactSpec = z.union([
   z.object({
diff --git a/lib/modules/manager/bazel/rules/oci.ts b/lib/modules/manager/bazel/rules/oci.ts
index 5e49791e88671b8b8cfa087833f9fc00d9921c19..e441db4ef53f784a1ac91cf6d96c1b0140e453df 100644
--- a/lib/modules/manager/bazel/rules/oci.ts
+++ b/lib/modules/manager/bazel/rules/oci.ts
@@ -3,7 +3,7 @@ import { DockerDatasource } from '../../../datasource/docker';
 import { id as dockerVersioning } from '../../../versioning/docker';
 import type { PackageDependency } from '../../types';
 
-export const ociRules = ['oci_pull'] as const;
+export const ociRules = ['oci_pull', '_oci_pull'] as const;
 
 export const OciTarget = z
   .object({