diff --git a/lib/modules/manager/flux/artifacts.spec.ts b/lib/modules/manager/flux/artifacts.spec.ts
index 35e767147674062bb7515fff29f69775b2f38417..9a7d507ec5094642e5208eff66243820798c3b92 100644
--- a/lib/modules/manager/flux/artifacts.spec.ts
+++ b/lib/modules/manager/flux/artifacts.spec.ts
@@ -48,6 +48,43 @@ describe('modules/manager/flux/artifacts', () => {
     ]);
   });
 
+  it('detects system manifests in subdirectories', async () => {
+    const snapshots = mockExecAll({ stdout: '', stderr: '' });
+    fs.readLocalFile.mockResolvedValueOnce('old');
+    fs.readLocalFile.mockResolvedValueOnce('test');
+
+    const res = await updateArtifacts({
+      packageFileName:
+        'clusters/my-cluster/flux-system/gitops-toolkit/gotk-components.yaml',
+      updatedDeps: [
+        {
+          newVersion: '1.0.1',
+          managerData: {
+            components:
+              'source-controller,kustomize-controller,helm-controller,notification-controller',
+          },
+        },
+      ],
+      newPackageFileContent: '',
+      config: {},
+    });
+
+    expect(res).toEqual([
+      {
+        file: {
+          type: 'addition',
+          path: 'clusters/my-cluster/flux-system/gitops-toolkit/gotk-components.yaml',
+          contents: 'test',
+        },
+      },
+    ]);
+    expect(snapshots).toMatchObject([
+      {
+        cmd: 'flux install --export --components source-controller,kustomize-controller,helm-controller,notification-controller > clusters/my-cluster/flux-system/gitops-toolkit/gotk-components.yaml',
+      },
+    ]);
+  });
+
   it('ignores non-system manifests', async () => {
     const res = await updateArtifacts({
       packageFileName: 'not-a-system-manifest.yaml',
diff --git a/lib/modules/manager/flux/common.ts b/lib/modules/manager/flux/common.ts
index b478f7a75d2e0988d17544fd4abc644b12c31725..320e7b9f31b92b3978f56b10fc94c00cd82847aa 100644
--- a/lib/modules/manager/flux/common.ts
+++ b/lib/modules/manager/flux/common.ts
@@ -1,6 +1,8 @@
 import { regEx } from '../../../util/regex';
 
-export const systemManifestRegex = '(^|/)flux-system/gotk-components\\.yaml$';
+export const systemManifestRegex =
+  '(^|\\/)flux-system\\/(?:.+\\/)?gotk-components\\.yaml$';
+
 export function isSystemManifest(file: string): boolean {
   return regEx(systemManifestRegex).test(file);
 }
diff --git a/lib/modules/manager/flux/readme.md b/lib/modules/manager/flux/readme.md
index 27a26f909b70ae0b12c2cde59ee61a28e8fecc91..ae2e4a33a47bde1d797e7933385c1d455241301a 100644
--- a/lib/modules/manager/flux/readme.md
+++ b/lib/modules/manager/flux/readme.md
@@ -31,7 +31,7 @@ Updating system manifests requires that either:
 
 ### Non-configured fileMatch
 
-By default, the `flux` manager will only match `flux-system/gotk-components.yaml` (i.e. system manifest) files.
+By default, the `flux` manager will only match `flux-system/{.,**}/gotk-components.yaml` (i.e. system manifest) files.
 
 This is because there is no commonly accepted file/directory naming convention for Flux manifests and we don't want to check every single `*.yaml` file in repositories just in case some of them have Flux definitions.