diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md
index f4e388e6f0d3b5e1510dee4739c77534370346e4..57e7e33536c9e025ba6e22193b3bd5d418bfc3a7 100644
--- a/docs/usage/self-hosted-configuration.md
+++ b/docs/usage/self-hosted-configuration.md
@@ -577,6 +577,10 @@ If this value is configured then Renovate:
 
 Renovate will then create branches on the fork and opens Pull Requests on the parent repository.
 
+<!-- prettier-ignore -->
+!!! note
+    Forked repositories will always be skipped when `forkToken` is set, even if `includeForks` is true.
+
 ## gitNoVerify
 
 Controls when Renovate passes the `--no-verify` flag to `git`.
diff --git a/lib/constants/error-messages.ts b/lib/constants/error-messages.ts
index 95daa453ee8ecbe07ee1f182e5c694a037fe3c26..490e96373341932b6c3cff5c0ee162224f19ff5b 100644
--- a/lib/constants/error-messages.ts
+++ b/lib/constants/error-messages.ts
@@ -28,6 +28,7 @@ export const REPOSITORY_CLOSED_ONBOARDING = 'disabled-closed-onboarding';
 export const REPOSITORY_DISABLED_BY_CONFIG = 'disabled-by-config';
 export const REPOSITORY_NO_CONFIG = 'disabled-no-config';
 export const REPOSITORY_EMPTY = 'empty';
+export const REPOSITORY_FORK_MODE_FORKED = 'fork-mode-forked';
 export const REPOSITORY_FORKED = 'fork';
 export const REPOSITORY_MIRRORED = 'mirror';
 export const REPOSITORY_NOT_FOUND = 'not-found';
diff --git a/lib/modules/platform/github/graphql.ts b/lib/modules/platform/github/graphql.ts
index 09f0addcc06a7c65637a471bf2641850185a2ab6..8f96b4f4fb0a3ae5dd9b7ac7748509e877c95745 100644
--- a/lib/modules/platform/github/graphql.ts
+++ b/lib/modules/platform/github/graphql.ts
@@ -3,6 +3,9 @@ query($owner: String!, $name: String!) {
   repository(owner: $owner, name: $name) {
     id
     isFork
+    parent {
+      nameWithOwner
+    }
     isArchived
     nameWithOwner
     hasIssuesEnabled
diff --git a/lib/modules/platform/github/index.spec.ts b/lib/modules/platform/github/index.spec.ts
index 11b8efe42f3857bf9a924575de3e69914346bec6..1f7e15ef8f6fd83e041ad0f30aaac7ceb303dfd0 100644
--- a/lib/modules/platform/github/index.spec.ts
+++ b/lib/modules/platform/github/index.spec.ts
@@ -7,6 +7,7 @@ import {
   PLATFORM_RATE_LIMIT_EXCEEDED,
   PLATFORM_UNKNOWN_ERROR,
   REPOSITORY_CANNOT_FORK,
+  REPOSITORY_FORKED,
   REPOSITORY_NOT_FOUND,
   REPOSITORY_RENAMED,
 } from '../../../constants/error-messages';
@@ -483,6 +484,7 @@ describe('modules/platform/github/index', () => {
     forkExisted: boolean,
     forkResult = 200,
     forkDefaultBranch = 'master',
+    isFork = false,
   ): void {
     scope
       // repo info
@@ -490,7 +492,7 @@ describe('modules/platform/github/index', () => {
       .reply(200, {
         data: {
           repository: {
-            isFork: false,
+            isFork,
             isArchived: false,
             nameWithOwner: repository,
             hasIssuesEnabled: true,
@@ -505,10 +507,10 @@ describe('modules/platform/github/index', () => {
             },
           },
         },
-      })
-      // getForks
-      .get(`/repos/${repository}/forks?per_page=100`)
-      .reply(
+      });
+
+    if (!isFork) {
+      scope.get(`/repos/${repository}/forks?per_page=100`).reply(
         forkResult,
         forkExisted
           ? [
@@ -520,6 +522,7 @@ describe('modules/platform/github/index', () => {
             ]
           : [],
       );
+    }
   }
 
   describe('initRepo', () => {
@@ -547,6 +550,19 @@ describe('modules/platform/github/index', () => {
       expect(config).toMatchSnapshot();
     });
 
+    it('throws if the repo is a fork', async () => {
+      const repo = 'some/repo';
+      const branch = 'master';
+      const scope = httpMock.scope(githubApiHost);
+      forkInitRepoMock(scope, repo, false, 200, branch, true);
+      await expect(
+        github.initRepo({
+          repository: 'some/repo',
+          forkToken: 'true',
+        }),
+      ).rejects.toThrow(REPOSITORY_FORKED);
+    });
+
     it('throws when cannot fork due to username error', async () => {
       const repo = 'some/repo';
       const branch = 'master';
diff --git a/lib/modules/platform/github/index.ts b/lib/modules/platform/github/index.ts
index c34abf4abcbf14be17cf62b6ebb2617ba6555edd..a5894572cd52db8669d843c646c8569facb80802 100644
--- a/lib/modules/platform/github/index.ts
+++ b/lib/modules/platform/github/index.ts
@@ -16,6 +16,7 @@ import {
   REPOSITORY_DISABLED,
   REPOSITORY_EMPTY,
   REPOSITORY_FORKED,
+  REPOSITORY_FORK_MODE_FORKED,
   REPOSITORY_NOT_FOUND,
   REPOSITORY_RENAMED,
 } from '../../../constants/error-messages';
@@ -570,6 +571,9 @@ export async function initRepo({
     if (err.message.startsWith('Repository access blocked')) {
       throw new Error(REPOSITORY_BLOCKED);
     }
+    if (err.message === REPOSITORY_FORK_MODE_FORKED) {
+      throw err;
+    }
     if (err.message === REPOSITORY_FORKED) {
       throw err;
     }
@@ -588,6 +592,15 @@ export async function initRepo({
 
   if (forkToken) {
     logger.debug('Bot is in fork mode');
+    if (repo.isFork) {
+      logger.debug(
+        `Forked repos cannot be processed when running with a forkToken, so this repo will be skipped`,
+      );
+      logger.debug(
+        `Parent repo for this forked repo is ${repo.parent?.nameWithOwner}`,
+      );
+      throw new Error(REPOSITORY_FORKED);
+    }
     config.forkOrg = forkOrg;
     config.forkToken = forkToken;
     // save parent name then delete
diff --git a/lib/modules/platform/github/types.ts b/lib/modules/platform/github/types.ts
index cd6feee577b74791e4abe02be012f24d1c76a6e2..f3c0e066619fada8221cb2dfb7b4bd381c596670 100644
--- a/lib/modules/platform/github/types.ts
+++ b/lib/modules/platform/github/types.ts
@@ -115,6 +115,9 @@ export type BranchProtection = any;
 export interface GhRepo {
   id: string;
   isFork: boolean;
+  parent?: {
+    nameWithOwner: string;
+  };
   isArchived: boolean;
   nameWithOwner: string;
   autoMergeAllowed: boolean;
diff --git a/lib/util/git/index.ts b/lib/util/git/index.ts
index 0cad95457e4b7e0ef398c932a35db4f3d8755879..5900222c072c115a1702ee00529b88c3f424c637 100644
--- a/lib/util/git/index.ts
+++ b/lib/util/git/index.ts
@@ -585,7 +585,7 @@ export async function getFileList(): Promise<string[]> {
 }
 
 export function getBranchList(): string[] {
-  return Object.keys(config.branchCommits);
+  return Object.keys(config.branchCommits ?? /* istanbul ignore next */ {});
 }
 
 export async function isBranchBehindBase(
diff --git a/lib/workers/repository/error.spec.ts b/lib/workers/repository/error.spec.ts
index 6b2ed7a118299c9101e43c6508376ba7dc84ef02..1c2a662370da8aac4582aae17e70e694950cf96e 100644
--- a/lib/workers/repository/error.spec.ts
+++ b/lib/workers/repository/error.spec.ts
@@ -18,6 +18,7 @@ import {
   REPOSITORY_DISABLED,
   REPOSITORY_EMPTY,
   REPOSITORY_FORKED,
+  REPOSITORY_FORK_MODE_FORKED,
   REPOSITORY_MIRRORED,
   REPOSITORY_NOT_FOUND,
   REPOSITORY_NO_PACKAGE_FILES,
@@ -47,6 +48,7 @@ describe('workers/repository/error', () => {
       REPOSITORY_DISABLED,
       REPOSITORY_CHANGED,
       REPOSITORY_FORKED,
+      REPOSITORY_FORK_MODE_FORKED,
       REPOSITORY_NO_PACKAGE_FILES,
       CONFIG_SECRETS_EXPOSED,
       CONFIG_VALIDATION,
diff --git a/lib/workers/repository/error.ts b/lib/workers/repository/error.ts
index 9433458deb14fcfc5e21a2c5e80c55ba460a628c..6e02b093158d78b0293f35fd25a5d311b98e868b 100644
--- a/lib/workers/repository/error.ts
+++ b/lib/workers/repository/error.ts
@@ -21,6 +21,7 @@ import {
   REPOSITORY_DISABLED_BY_CONFIG,
   REPOSITORY_EMPTY,
   REPOSITORY_FORKED,
+  REPOSITORY_FORK_MODE_FORKED,
   REPOSITORY_MIRRORED,
   REPOSITORY_NOT_FOUND,
   REPOSITORY_NO_CONFIG,
@@ -93,6 +94,12 @@ export default async function handleError(
     logger.error('Repository is not found');
     return err.message;
   }
+  if (err.message === REPOSITORY_FORK_MODE_FORKED) {
+    logger.info(
+      'Repository is a fork and cannot be processed when Renovate is running in fork mode itself',
+    );
+    return err.message;
+  }
   if (err.message === REPOSITORY_FORKED) {
     logger.info(
       'Repository is a fork and not manually configured - skipping - did you want to run with --fork-processing=enabled?',
diff --git a/lib/workers/repository/result.ts b/lib/workers/repository/result.ts
index 83829671885d8c5a1f4405f80767bf003727ea0c..70ba5f0c57d9d426ade2df57491923d7faec5638 100644
--- a/lib/workers/repository/result.ts
+++ b/lib/workers/repository/result.ts
@@ -12,6 +12,7 @@ import {
   REPOSITORY_DISABLED_BY_CONFIG,
   REPOSITORY_EMPTY,
   REPOSITORY_FORKED,
+  REPOSITORY_FORK_MODE_FORKED,
   REPOSITORY_MIRRORED,
   REPOSITORY_NOT_FOUND,
   REPOSITORY_NO_CONFIG,
@@ -47,6 +48,7 @@ export function processResult(
     REPOSITORY_DISABLED,
     REPOSITORY_DISABLED_BY_CONFIG,
     REPOSITORY_EMPTY,
+    REPOSITORY_FORK_MODE_FORKED,
     REPOSITORY_FORKED,
     REPOSITORY_MIRRORED,
     REPOSITORY_NOT_FOUND,