diff --git a/lib/modules/datasource/metadata.ts b/lib/modules/datasource/metadata.ts
index cbe96e040eb5ad46267ab499e90b9d71a73e630b..c0b1cd6a5de6f3f58c27acf402a99d847f9240c7 100644
--- a/lib/modules/datasource/metadata.ts
+++ b/lib/modules/datasource/metadata.ts
@@ -5,7 +5,7 @@ import { detectPlatform } from '../../util/common';
 import { parseGitUrl } from '../../util/git/url';
 import * as hostRules from '../../util/host-rules';
 import { regEx } from '../../util/regex';
-import { parseUrl, trimTrailingSlash, validateUrl } from '../../util/url';
+import { isHttpUrl, parseUrl, trimTrailingSlash } from '../../util/url';
 import { manualChangelogUrls, manualSourceUrls } from './metadata-manual';
 import type { ReleaseResult } from './types';
 
@@ -195,7 +195,7 @@ export function addMetaData(
   ];
   for (const urlKey of urlKeys) {
     const urlVal = dep[urlKey];
-    if (is.string(urlVal) && validateUrl(urlVal.trim())) {
+    if (is.string(urlVal) && isHttpUrl(urlVal.trim())) {
       dep[urlKey] = urlVal.trim() as never;
     } else {
       delete dep[urlKey];
diff --git a/lib/modules/datasource/npm/npmrc.ts b/lib/modules/datasource/npm/npmrc.ts
index ad605fe4ff2bc727c8cdd5e5bf27dcfb40b20ca7..73b2e1eef52896096410b2855b5e55fb953d2e93 100644
--- a/lib/modules/datasource/npm/npmrc.ts
+++ b/lib/modules/datasource/npm/npmrc.ts
@@ -8,7 +8,7 @@ import type { HostRule } from '../../../types';
 import * as hostRules from '../../../util/host-rules';
 import { regEx } from '../../../util/regex';
 import { fromBase64 } from '../../../util/string';
-import { ensureTrailingSlash, validateUrl } from '../../../util/url';
+import { ensureTrailingSlash, isHttpUrl } from '../../../util/url';
 import { defaultRegistryUrls } from './common';
 import type { NpmrcRules } from './types';
 
@@ -89,7 +89,7 @@ export function convertNpmrcToRules(npmrc: Record<string, any>): NpmrcRules {
   const { registry } = npmrc;
   // packageRules order matters, so look for a default registry first
   if (is.nonEmptyString(registry)) {
-    if (validateUrl(registry)) {
+    if (isHttpUrl(registry)) {
       // Default registry
       rules.packageRules?.push({
         matchDatasources,
@@ -108,7 +108,7 @@ export function convertNpmrcToRules(npmrc: Record<string, any>): NpmrcRules {
     const keyType = keyParts.pop();
     if (keyType === 'registry' && keyParts.length && is.nonEmptyString(value)) {
       const scope = keyParts.join(':');
-      if (validateUrl(value)) {
+      if (isHttpUrl(value)) {
         rules.packageRules?.push({
           matchDatasources,
           matchPackagePrefixes: [scope + '/'],
diff --git a/lib/modules/datasource/terraform-module/index.ts b/lib/modules/datasource/terraform-module/index.ts
index 9476cef7e5c3c35caf59f9ef670e2754b9c63fcf..fe89239f194926db268859e95d9ce46ab472fdc5 100644
--- a/lib/modules/datasource/terraform-module/index.ts
+++ b/lib/modules/datasource/terraform-module/index.ts
@@ -2,7 +2,7 @@ import { logger } from '../../../logger';
 import { cache } from '../../../util/cache/package/decorator';
 import { regEx } from '../../../util/regex';
 import { coerceString } from '../../../util/string';
-import { validateUrl } from '../../../util/url';
+import { isHttpUrl } from '../../../util/url';
 import * as hashicorpVersioning from '../../versioning/hashicorp';
 import type { GetReleasesConfig, ReleaseResult } from '../types';
 import { TerraformDatasource } from './base';
@@ -162,7 +162,7 @@ export class TerraformModuleDatasource extends TerraformDatasource {
     };
 
     // Add the source URL if given
-    if (validateUrl(res.modules[0].source)) {
+    if (isHttpUrl(res.modules[0].source)) {
       dep.sourceUrl = res.modules[0].source;
     }
 
diff --git a/lib/modules/datasource/terraform-module/utils.ts b/lib/modules/datasource/terraform-module/utils.ts
index e3449faa23f039a11bdc6e2507568be54bffe418..b6f981f1dc6d88c2d8f0df1c991cbcd31febc5cb 100644
--- a/lib/modules/datasource/terraform-module/utils.ts
+++ b/lib/modules/datasource/terraform-module/utils.ts
@@ -1,4 +1,4 @@
-import { joinUrlParts, validateUrl } from '../../../util/url';
+import { isHttpUrl, joinUrlParts } from '../../../util/url';
 import type {
   ServiceDiscoveryEndpointType,
   ServiceDiscoveryResult,
@@ -12,7 +12,7 @@ export function createSDBackendURL(
 ): string {
   const sdEndpoint = sdResult[sdType] ?? '';
   const fullPath = joinUrlParts(sdEndpoint, subPath);
-  if (validateUrl(fullPath)) {
+  if (isHttpUrl(fullPath)) {
     return fullPath;
   }
   return joinUrlParts(registryURL, fullPath);
diff --git a/lib/modules/manager/npm/post-update/rules.ts b/lib/modules/manager/npm/post-update/rules.ts
index 116704478acffd5231d5678209bfe50150914bd3..59380f7a616a968bd9164ff26ea1a979a07b5adb 100644
--- a/lib/modules/manager/npm/post-update/rules.ts
+++ b/lib/modules/manager/npm/post-update/rules.ts
@@ -2,7 +2,7 @@ import is from '@sindresorhus/is';
 import * as hostRules from '../../../../util/host-rules';
 import { regEx } from '../../../../util/regex';
 import { toBase64 } from '../../../../util/string';
-import { validateUrl } from '../../../../util/url';
+import { isHttpUrl } from '../../../../util/url';
 
 export interface HostRulesResult {
   additionalNpmrcContent: string[];
@@ -21,7 +21,7 @@ export function processHostRules(): HostRulesResult {
     if (hostRule.resolvedHost) {
       let uri = hostRule.matchHost;
       uri =
-        is.string(uri) && validateUrl(uri)
+        is.string(uri) && isHttpUrl(uri)
           ? uri.replace(regEx(/^https?:/), '')
           : // TODO: types (#22198)
             `//${uri}/`;
diff --git a/lib/util/git/auth.ts b/lib/util/git/auth.ts
index d22abd171634120440d1695a6774c02bc7d21c77..c776b3c4831031e3273e1dc63ba2b969c8a5a54b 100644
--- a/lib/util/git/auth.ts
+++ b/lib/util/git/auth.ts
@@ -4,7 +4,7 @@ import type { HostRule } from '../../types';
 import { detectPlatform } from '../common';
 import { find, getAll } from '../host-rules';
 import { regEx } from '../regex';
-import { createURLFromHostOrURL, validateUrl } from '../url';
+import { createURLFromHostOrURL, isHttpUrl } from '../url';
 import type { AuthenticationRule } from './types';
 import { parseGitUrl } from './url';
 
@@ -203,7 +203,7 @@ function addAuthFromHostRule(
 ): NodeJS.ProcessEnv {
   let environmentVariables = env;
   const httpUrl = createURLFromHostOrURL(hostRule.matchHost!)?.toString();
-  if (validateUrl(httpUrl)) {
+  if (isHttpUrl(httpUrl)) {
     logger.trace(`Adding Git authentication for ${httpUrl} using token auth.`);
     environmentVariables = getGitAuthenticatedEnvironmentVariables(
       httpUrl!,
diff --git a/lib/util/host-rules.ts b/lib/util/host-rules.ts
index 39ff6b65e006d06de02a5f25e95c92b82a725044..bae2c3f5c160b7908a946641343e076f177f2a75 100644
--- a/lib/util/host-rules.ts
+++ b/lib/util/host-rules.ts
@@ -6,7 +6,7 @@ import type { CombinedHostRule, HostRule } from '../types';
 import { clone } from './clone';
 import * as sanitize from './sanitize';
 import { toBase64 } from './string';
-import { parseUrl, validateUrl } from './url';
+import { isHttpUrl, parseUrl } from './url';
 
 let hostRules: HostRule[] = [];
 
@@ -108,7 +108,7 @@ function isOnlyMatchHost(
 }
 
 function matchesHost(url: string, matchHost: string): boolean {
-  if (validateUrl(url) && validateUrl(matchHost)) {
+  if (isHttpUrl(url) && isHttpUrl(matchHost)) {
     return url.startsWith(matchHost);
   }
 
diff --git a/lib/util/http/gerrit.ts b/lib/util/http/gerrit.ts
index a163da021fc5ee33fa17e2117e56e14694e1d4b8..a690ba951b3147e660566b4670228e475dcaa58d 100644
--- a/lib/util/http/gerrit.ts
+++ b/lib/util/http/gerrit.ts
@@ -1,6 +1,6 @@
 import { parseJson } from '../common';
 import { regEx } from '../regex';
-import { validateUrl } from '../url';
+import { isHttpUrl } from '../url';
 import type { HttpOptions, HttpResponse, InternalHttpOptions } from './types';
 import { Http } from './index';
 
@@ -24,7 +24,7 @@ export class GerritHttp extends Http {
     path: string,
     options?: InternalHttpOptions,
   ): Promise<HttpResponse<T>> {
-    const url = validateUrl(path) ? path : baseUrl + path;
+    const url = isHttpUrl(path) ? path : baseUrl + path;
     const opts: InternalHttpOptions = {
       parseJson: (text: string) =>
         parseJson(text.replace(GerritHttp.magicPrefix, ''), path),
diff --git a/lib/util/url.spec.ts b/lib/util/url.spec.ts
index cbc946437275548e7856400b9abb334450c8955b..a0c65cb7ae27b1bc57873dee1f361bec28e3e4fb 100644
--- a/lib/util/url.spec.ts
+++ b/lib/util/url.spec.ts
@@ -3,6 +3,7 @@ import {
   ensurePathPrefix,
   ensureTrailingSlash,
   getQueryString,
+  isHttpUrl,
   joinUrlParts,
   parseLinkHeader,
   parseUrl,
@@ -10,7 +11,6 @@ import {
   resolveBaseUrl,
   trimSlashes,
   trimTrailingSlash,
-  validateUrl,
 } from './url';
 
 describe('util/url', () => {
@@ -97,15 +97,14 @@ describe('util/url', () => {
     expect(getQueryString({ a: 1, b: [1, 2] })).toBe('a=1&b=1&b=2');
   });
 
-  it('validates URLs', () => {
-    expect(validateUrl(undefined)).toBeFalse();
-    expect(validateUrl('')).toBeFalse();
-    expect(validateUrl(null)).toBeFalse();
-    expect(validateUrl('foo')).toBeFalse();
-    expect(validateUrl('ssh://github.com')).toBeFalse();
-    expect(validateUrl('http://github.com')).toBeTrue();
-    expect(validateUrl('https://github.com')).toBeTrue();
-    expect(validateUrl('https://github.com', false)).toBeTrue();
+  it('validates http-based URLs', () => {
+    expect(isHttpUrl(undefined)).toBeFalse();
+    expect(isHttpUrl('')).toBeFalse();
+    expect(isHttpUrl(null)).toBeFalse();
+    expect(isHttpUrl('foo')).toBeFalse();
+    expect(isHttpUrl('ssh://github.com')).toBeFalse();
+    expect(isHttpUrl('http://github.com')).toBeTrue();
+    expect(isHttpUrl('https://github.com')).toBeTrue();
   });
 
   it('parses URL', () => {
diff --git a/lib/util/url.ts b/lib/util/url.ts
index c28d421e41c389b3a876802e4f2c8682579db0ec..9ac957233127ff2305cb3fd08fe627c6d2ec73c5 100644
--- a/lib/util/url.ts
+++ b/lib/util/url.ts
@@ -85,16 +85,13 @@ export function getQueryString(params: Record<string, any>): string {
   return usp.toString();
 }
 
-export function validateUrl(
-  url: string | null | undefined,
-  httpOnly = true,
-): boolean {
+export function isHttpUrl(url: unknown): boolean {
   if (!is.nonEmptyString(url)) {
     return false;
   }
   try {
     const { protocol } = new URL(url);
-    return httpOnly ? !!protocol.startsWith('http') : !!protocol;
+    return protocol === 'https:' || protocol === 'http:';
   } catch (err) {
     return false;
   }
diff --git a/lib/workers/repository/update/pr/changelog/release-notes.ts b/lib/workers/repository/update/pr/changelog/release-notes.ts
index 79d62f5d0ade941ca637356fafae836cb51a5c75..bdf4a34bd637ffe7fce5c043d0da6b245885ca14 100644
--- a/lib/workers/repository/update/pr/changelog/release-notes.ts
+++ b/lib/workers/repository/update/pr/changelog/release-notes.ts
@@ -9,7 +9,7 @@ import { detectPlatform } from '../../../../../util/common';
 import { linkify } from '../../../../../util/markdown';
 import { newlineRegex, regEx } from '../../../../../util/regex';
 import { coerceString } from '../../../../../util/string';
-import { validateUrl } from '../../../../../util/url';
+import { isHttpUrl } from '../../../../../util/url';
 import type { BranchUpgradeConfig } from '../../../../types';
 import * as bitbucket from './bitbucket';
 import * as gitea from './gitea';
@@ -346,12 +346,12 @@ export async function getReleaseNotesMd(
             .filter(Boolean);
           let body = section.replace(regEx(/.*?\n(-{3,}\n)?/), '').trim();
           for (const word of title) {
-            if (word.includes(version) && !validateUrl(word)) {
+            if (word.includes(version) && !isHttpUrl(word)) {
               logger.trace({ body }, 'Found release notes for v' + version);
               // TODO: fix url
               const notesSourceUrl = `${baseUrl}${repository}/blob/HEAD/${changelogFile}`;
               const mdHeadingLink = title
-                .filter((word) => !validateUrl(word))
+                .filter((word) => !isHttpUrl(word))
                 .join('-')
                 .replace(regEx(/[^A-Za-z0-9-]/g), '');
               const url = `${notesSourceUrl}#${mdHeadingLink}`;