diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md
index 0a0bd42b6bb530a12e1c56e505d1b0f1a8925ffe..66f2f3fc9341deb10c6dc0c27c70b7faf7bf3e71 100644
--- a/docs/usage/self-hosted-configuration.md
+++ b/docs/usage/self-hosted-configuration.md
@@ -553,6 +553,12 @@ You can choose from the following behaviors for the `dryRun` config option:
 
 Information provided mainly in debug log level.
 
+## encryptedWarning
+
+Use this if you want to stop supporting `encrypted` configuration capabilities but want to warn users first to migrate.
+
+If set to a string value, Renovate will log warnings with the `encryptedWarning` text, meaning the message will be visible to users such as on the Dependency Dashboard.
+
 ## endpoint
 
 ## executionTimeout
diff --git a/lib/config/decrypt.spec.ts b/lib/config/decrypt.spec.ts
index 8cde4a0378d6e33aed86371eea7c6127056131a3..66d73753ebb2672cd83cc0ab545d57d19680680d 100644
--- a/lib/config/decrypt.spec.ts
+++ b/lib/config/decrypt.spec.ts
@@ -1,3 +1,4 @@
+import { logger } from '../../test/util';
 import { decryptConfig } from './decrypt';
 import { GlobalConfig } from './global';
 import type { RenovateConfig } from './types';
@@ -21,7 +22,11 @@ describe('config/decrypt', () => {
 
     it('warns if no privateKey found', async () => {
       config.encrypted = { a: '1' };
+      GlobalConfig.set({ encryptedWarning: 'text' });
+
       const res = await decryptConfig(config, repository);
+
+      expect(logger.logger.once.warn).toHaveBeenCalledWith('text');
       expect(res.encrypted).toBeUndefined();
       expect(res.a).toBeUndefined();
     });
diff --git a/lib/config/decrypt.ts b/lib/config/decrypt.ts
index 1895b6dc8ff698a8db0f5ad285ee4243c5e004a9..09443ad5f4c835a9a4e7f718b153b430dc75fcd3 100644
--- a/lib/config/decrypt.ts
+++ b/lib/config/decrypt.ts
@@ -134,6 +134,12 @@ export async function decryptConfig(
   for (const [key, val] of Object.entries(config)) {
     if (key === 'encrypted' && is.object(val)) {
       logger.debug({ config: val }, 'Found encrypted config');
+
+      const encryptedWarning = GlobalConfig.get('encryptedWarning');
+      if (is.string(encryptedWarning)) {
+        logger.once.warn(encryptedWarning);
+      }
+
       if (privateKey) {
         for (const [eKey, eVal] of Object.entries(val)) {
           logger.debug('Trying to decrypt ' + eKey);
diff --git a/lib/config/global.ts b/lib/config/global.ts
index 1077299e45aca7ddc5b1b5820c2462015abfca10..b006feb98f411286920b221d420c626dd47c26dd 100644
--- a/lib/config/global.ts
+++ b/lib/config/global.ts
@@ -21,6 +21,7 @@ export class GlobalConfig {
     'dockerSidecarImage',
     'dockerUser',
     'dryRun',
+    'encryptedWarning',
     'exposeAllEnv',
     'executionTimeout',
     'githubTokenWarn',
diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts
index cd4e754f9c184bdc5150705ea05020b5ead92074..2441f7dcd35d4f01910692542ef4a5e237679d4e 100644
--- a/lib/config/options/index.ts
+++ b/lib/config/options/index.ts
@@ -647,10 +647,17 @@ const options: RenovateOptions[] = [
     default: true,
     globalOnly: true,
   },
+  {
+    name: 'encryptedWarning',
+    description: 'Warning text to use if encrypted config is found.',
+    type: 'string',
+    globalOnly: true,
+    advancedUse: true,
+  },
   {
     name: 'inheritConfig',
     description:
-      'If `true`, Renovate will inherit configuration from the `inheritConfigFileName` file in `inheritConfigRepoName',
+      'If `true`, Renovate will inherit configuration from the `inheritConfigFileName` file in `inheritConfigRepoName`.',
     type: 'boolean',
     default: false,
     globalOnly: true,
diff --git a/lib/config/types.ts b/lib/config/types.ts
index 2129fd9b7ecc2b36b5de045461723bbdb430f04a..8dfcfc3d5977f48e1ee5cd315da554c4a4674cfc 100644
--- a/lib/config/types.ts
+++ b/lib/config/types.ts
@@ -147,6 +147,7 @@ export interface RepoGlobalConfig {
   dockerSidecarImage?: string;
   dockerUser?: string;
   dryRun?: DryRunConfig;
+  encryptedWarning?: string;
   endpoint?: string;
   executionTimeout?: number;
   exposeAllEnv?: boolean;