diff --git a/db/post_migrate/20240923090549_fix_inconsistent_organization_id.rb b/db/post_migrate/20240923090549_fix_inconsistent_organization_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4399d24324f2226fa3a8c2884331e087ba0f3461
--- /dev/null
+++ b/db/post_migrate/20240923090549_fix_inconsistent_organization_id.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+class FixInconsistentOrganizationId < Gitlab::Database::Migration[2.2]
+  milestone '17.5'
+
+  restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
+
+  def process_hierarchy(namespace)
+    organization_id = namespace['organization_id']
+    parent_id = namespace['id']
+
+    execute("
+      UPDATE namespaces
+      SET organization_id = #{organization_id}
+      WHERE parent_id = #{parent_id} AND organization_id != #{organization_id}
+    ")
+    execute("
+      UPDATE projects
+      SET organization_id = #{organization_id}
+      WHERE namespace_id = #{parent_id}
+      AND organization_id != #{organization_id}
+    ")
+
+    query = "SELECT id, organization_id, type FROM namespaces WHERE parent_id = #{parent_id}"
+    select_all(query).each do |child|
+      process_hierarchy(child)
+    end
+  end
+
+  def up
+    query = "SELECT id, organization_id, parent_id FROM namespaces WHERE organization_id > 1 AND parent_id IS NULL"
+    select_all(query).each do |namespace|
+      process_hierarchy(namespace)
+    end
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/schema_migrations/20240923090549 b/db/schema_migrations/20240923090549
new file mode 100644
index 0000000000000000000000000000000000000000..de4f319cea1310904c26e6c5d78d31f50986559b
--- /dev/null
+++ b/db/schema_migrations/20240923090549
@@ -0,0 +1 @@
+35442f00892a8eeb83e52702c57ee1efa083667fb64487c48594b4b92ae3442a
\ No newline at end of file
diff --git a/spec/migrations/db/post_migrate/20240923090549_fix_inconsistent_organization_id_spec.rb b/spec/migrations/db/post_migrate/20240923090549_fix_inconsistent_organization_id_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9659b27fac96a826d927d02d0009f89530201736
--- /dev/null
+++ b/spec/migrations/db/post_migrate/20240923090549_fix_inconsistent_organization_id_spec.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe FixInconsistentOrganizationId, migration: :gitlab_main, feature_category: :cell do
+  # Inconsistent data:
+  let!(:parent_namespace_1) do
+    table(:namespaces).create!(type: 'Group', name: 'parent', path: 'parent', organization_id: 2)
+  end
+
+  let!(:namespace_1) do
+    table(:namespaces).create!(type: 'Group', name: 'child', path: 'child', parent_id: parent_namespace_1.id,
+      organization_id: 3)
+  end
+
+  let!(:namespace_2) do
+    table(:namespaces).create!(type: 'Group', name: 'parent group of project', path: 'parent-group-of-project',
+      organization_id: 4)
+  end
+
+  let!(:project_namespace_1) do
+    table(:namespaces).create!(type: 'Project', name: 'project namespace', path: 'project_namespace',
+      organization_id: 5)
+  end
+
+  let!(:project_1) do
+    table(:projects).create!(namespace_id: namespace_2.id,
+      project_namespace_id: project_namespace_1.id, organization_id: 5)
+  end
+
+  let!(:namespace_2_1) do
+    table(:namespaces).create!(parent_id: namespace_2.id, type: 'Group', name: 'sub-group of project',
+      path: 'sub-group-of-project', organization_id: 6)
+  end
+
+  let!(:project_namespace_2_1) do
+    table(:namespaces).create!(type: 'Project', name: 'project namespace 2 1', path: 'project_namespace-2-1',
+      organization_id: 7)
+  end
+
+  let!(:project_2_1) do
+    table(:projects).create!(namespace_id: namespace_2_1.id,
+      project_namespace_id: project_namespace_2_1.id, organization_id: 7)
+  end
+
+  # Valid data
+  let!(:parent_namespace_2) do
+    table(:namespaces).create!(type: 'Group', name: 'parent 2', path: 'parent2', organization_id: 8)
+  end
+
+  let!(:namespace_3) do
+    table(:namespaces).create!(type: 'Group', name: 'child 2', path: 'child2', parent_id: parent_namespace_2.id,
+      organization_id: 8)
+  end
+
+  let!(:namespace_4) do
+    table(:namespaces).create!(type: 'Group', name: 'parent of project 2', path: 'parent-of-project-2 ',
+      organization_id: 9)
+  end
+
+  let!(:project_namespace_2) do
+    table(:namespaces).create!(type: 'Project', name: 'project namespace 2', path: 'project_namespace_2',
+      organization_id: 9)
+  end
+
+  let!(:project_2) do
+    table(:projects).create!(namespace_id: namespace_4.id,
+      project_namespace_id: project_namespace_2.id, organization_id: 9)
+  end
+
+  describe '#up' do
+    it 'sets organization_id to parent organization if organization_ids do not match' do
+      migrate!
+
+      expect(namespace_1.reload.organization_id).to eq(2)
+      expect(project_1.reload.organization_id).to eq(4)
+      expect(project_2_1.reload.organization_id).to eq(4)
+
+      expect(namespace_3.reload.organization_id).to eq(8)
+      expect(project_2.reload.organization_id).to eq(9)
+    end
+  end
+end