diff --git a/lib/config/validation.spec.ts b/lib/config/validation.spec.ts
index 37b19ebe5ca5b9c6b617200bf6055b51c5801476..785fd217b2e67fcd6006ba9e6f3b9aac740466c7 100644
--- a/lib/config/validation.spec.ts
+++ b/lib/config/validation.spec.ts
@@ -444,13 +444,51 @@ describe('config/validation', () => {
       `);
     });
 
+    it('errors if invalid regexManager customType', async () => {
+      const config = {
+        regexManagers: [
+          {
+            customType: 'unknown',
+            fileMatch: ['some-file'],
+            matchStrings: ['^(?<depName>foo)(?<currentValue>bar)$'],
+            datasourceTemplate: 'maven',
+            versioningTemplate: 'gradle',
+          },
+        ],
+      };
+      const { warnings, errors } = await configValidation.validateConfig(
+        config as any,
+        true
+      );
+      expect(warnings).toHaveLength(0);
+      expect(errors).toHaveLength(1);
+      expect(errors).toMatchInlineSnapshot(`
+        [
+          {
+            "message": "Invalid customType: unknown. Key is not a custom manager",
+            "topic": "Configuration Error",
+          },
+        ]
+      `);
+    });
+
     it('errors if empty regexManager matchStrings', async () => {
       const config = {
         regexManagers: [
-          { customType: 'regex', fileMatch: ['foo'], matchStrings: [] },
           {
             customType: 'regex',
             fileMatch: ['foo'],
+            matchStrings: [],
+            depNameTemplate: 'foo',
+            datasourceTemplate: 'bar',
+            currentValueTemplate: 'baz',
+          },
+          {
+            customType: 'regex',
+            fileMatch: ['foo'],
+            depNameTemplate: 'foo',
+            datasourceTemplate: 'bar',
+            currentValueTemplate: 'baz',
           },
         ],
       };
@@ -499,6 +537,9 @@ describe('config/validation', () => {
             customType: 'regex',
             fileMatch: ['Dockerfile'],
             matchStrings: ['***$}{]]['],
+            depNameTemplate: 'foo',
+            datasourceTemplate: 'bar',
+            currentValueTemplate: 'baz',
           },
         ],
       };
@@ -510,6 +551,26 @@ describe('config/validation', () => {
       expect(errors).toHaveLength(1);
     });
 
+    // testing if we get all errors at once or not (possible), this does not include customType or fileMatch
+    // since they are common to all custom managers
+    it('validates all possible regex manager options', async () => {
+      const config: RenovateConfig = {
+        regexManagers: [
+          {
+            customType: 'regex',
+            fileMatch: ['Dockerfile'],
+            matchStrings: ['***$}{]]['], // invalid matchStrings regex, no depName, datasource and currentValue
+          },
+        ],
+      };
+      const { warnings, errors } = await configValidation.validateConfig(
+        config,
+        true
+      );
+      expect(warnings).toHaveLength(0);
+      expect(errors).toHaveLength(4);
+    });
+
     it('passes if regexManager fields are present', async () => {
       const config: RenovateConfig = {
         regexManagers: [
diff --git a/lib/config/validation.ts b/lib/config/validation.ts
index e1cf284e3b304ce65e360ae64a351ce3d5ac9b9d..7679a7379a3dd7c56f290f9d2182f5e3f66f4842 100644
--- a/lib/config/validation.ts
+++ b/lib/config/validation.ts
@@ -1,5 +1,7 @@
 import is from '@sindresorhus/is';
 import { allManagersList, getManagerList } from '../modules/manager';
+import { isCustomManager } from '../modules/manager/custom';
+import type { RegexManagerConfig } from '../modules/manager/custom/regex/types';
 import { configRegexPredicate, isConfigRegex, regEx } from '../util/regex';
 import * as template from '../util/template';
 import {
@@ -10,6 +12,8 @@ import { migrateConfig } from './migration';
 import { getOptions } from './options';
 import { resolveConfigPresets } from './presets';
 import type {
+  CustomManager,
+  RegexManagerTemplates,
   RenovateConfig,
   RenovateOptions,
   ValidationMessage,
@@ -416,8 +420,7 @@ export async function validateConfig(
                 'autoReplaceStringTemplate',
                 'depTypeTemplate',
               ];
-              // TODO: fix types #22198
-              for (const regexManager of val as any[]) {
+              for (const regexManager of val as CustomManager[]) {
                 if (
                   Object.keys(regexManager).some(
                     (k) => !allowedKeys.includes(k)
@@ -432,49 +435,19 @@ export async function validateConfig(
                       ', '
                     )}`,
                   });
-                } else if (is.nonEmptyString(regexManager.customType)) {
+                } else if (
+                  is.nonEmptyString(regexManager.customType) &&
+                  isCustomManager(regexManager.customType)
+                ) {
                   if (is.nonEmptyArray(regexManager.fileMatch)) {
-                    if (is.nonEmptyArray(regexManager.matchStrings)) {
-                      let validRegex = false;
-                      for (const matchString of regexManager.matchStrings) {
-                        try {
-                          regEx(matchString);
-                          validRegex = true;
-                        } catch (e) {
-                          errors.push({
-                            topic: 'Configuration Error',
-                            message: `Invalid regExp for ${currentPath}: \`${String(
-                              matchString
-                            )}\``,
-                          });
-                        }
-                      }
-                      if (validRegex) {
-                        const mandatoryFields = [
-                          'depName',
-                          'currentValue',
-                          'datasource',
-                        ];
-                        for (const field of mandatoryFields) {
-                          if (
-                            !regexManager[`${field}Template`] &&
-                            !regexManager.matchStrings.some(
-                              (matchString: string) =>
-                                matchString.includes(`(?<${field}>`)
-                            )
-                          ) {
-                            errors.push({
-                              topic: 'Configuration Error',
-                              message: `Regex Managers must contain ${field}Template configuration or regex group named ${field}`,
-                            });
-                          }
-                        }
-                      }
-                    } else {
-                      errors.push({
-                        topic: 'Configuration Error',
-                        message: `Each Regex Manager must contain a non-empty matchStrings array`,
-                      });
+                    switch (regexManager.customType) {
+                      case 'regex':
+                        validateRegexManagerFields(
+                          regexManager,
+                          currentPath,
+                          errors
+                        );
+                        break;
                     }
                   } else {
                     errors.push({
@@ -483,10 +456,20 @@ export async function validateConfig(
                     });
                   }
                 } else {
-                  errors.push({
-                    topic: 'Configuration Error',
-                    message: `Each Regex Manager must contain a non-empty customType string`,
-                  });
+                  if (
+                    is.emptyString(regexManager.customType) ||
+                    is.undefined(regexManager.customType)
+                  ) {
+                    errors.push({
+                      topic: 'Configuration Error',
+                      message: `Each Regex Manager must contain a non-empty customType string`,
+                    });
+                  } else {
+                    errors.push({
+                      topic: 'Configuration Error',
+                      message: `Invalid customType: ${regexManager.customType}. Key is not a custom manager`,
+                    });
+                  }
                 }
               }
             }
@@ -672,3 +655,43 @@ export async function validateConfig(
   warnings.sort(sortAll);
   return { errors, warnings };
 }
+
+function validateRegexManagerFields(
+  regexManager: RegexManagerConfig,
+  currentPath: string,
+  errors: ValidationMessage[]
+): void {
+  if (is.nonEmptyArray(regexManager.matchStrings)) {
+    for (const matchString of regexManager.matchStrings) {
+      try {
+        regEx(matchString);
+      } catch (e) {
+        errors.push({
+          topic: 'Configuration Error',
+          message: `Invalid regExp for ${currentPath}: \`${matchString}\``,
+        });
+      }
+    }
+  } else {
+    errors.push({
+      topic: 'Configuration Error',
+      message: `Each Regex Manager must contain a non-empty matchStrings array`,
+    });
+  }
+
+  const mandatoryFields = ['depName', 'currentValue', 'datasource'];
+  for (const field of mandatoryFields) {
+    const templateField = `${field}Template` as keyof RegexManagerTemplates;
+    if (
+      !regexManager[templateField] &&
+      !regexManager.matchStrings.some((matchString) =>
+        matchString.includes(`(?<${field}>`)
+      )
+    ) {
+      errors.push({
+        topic: 'Configuration Error',
+        message: `Regex Managers must contain ${field}Template configuration or regex group named ${field}`,
+      });
+    }
+  }
+}