diff --git a/app/models/issue.rb b/app/models/issue.rb
index 405dae85488547b1d3bad8f3fc5ecaa6d5eafd6e..47dc084d69cf7d0c5ec2cb6cc6222217f9eeed85 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -204,6 +204,8 @@ class Issue < ApplicationRecord
     before_transition closed: :opened do |issue|
       issue.closed_at = nil
       issue.closed_by = nil
+
+      issue.clear_closure_reason_references
     end
   end
 
@@ -379,6 +381,11 @@ class Issue < ApplicationRecord
     !duplicated_to_id.nil?
   end
 
+  def clear_closure_reason_references
+    self.moved_to_id = nil
+    self.duplicated_to_id = nil
+  end
+
   def can_move?(user, to_project = nil)
     if to_project
       return false unless user.can?(:admin_issue, to_project)
diff --git a/ee/app/models/ee/issue.rb b/ee/app/models/ee/issue.rb
index 51801b9d08263d4b8ae12b7b0bd352322a1a6e75..daa8de8f6885438c7c1172be6e077b8609f7b2b8 100644
--- a/ee/app/models/ee/issue.rb
+++ b/ee/app/models/ee/issue.rb
@@ -167,6 +167,13 @@ module EE
       !!promoted_to_epic_id
     end
 
+    override :clear_closure_reason_references
+    def clear_closure_reason_references
+      super
+
+      self.promoted_to_epic_id = nil
+    end
+
     class_methods do
       extend ::Gitlab::Utils::Override
 
diff --git a/ee/spec/models/issue_spec.rb b/ee/spec/models/issue_spec.rb
index c274957b2901abd10fb5a4efba81225b460e77e8..7ef4baadefa6fb9cf80556c426f12bd4b36d557d 100644
--- a/ee/spec/models/issue_spec.rb
+++ b/ee/spec/models/issue_spec.rb
@@ -492,6 +492,15 @@ RSpec.describe Issue do
     end
   end
 
+  describe '#reopen' do
+    let(:promoted_to_epic) { create(:epic) }
+    let(:issue) { create(:issue, :closed, promoted_to_epic: promoted_to_epic) }
+
+    it 'clears promoted_to_epic_id for promoted issues' do
+      expect { issue.reopen }.to change { issue.promoted_to_epic_id }.from(promoted_to_epic.id).to(nil)
+    end
+  end
+
   context 'ES related specs', :elastic do
     before do
       stub_ee_application_setting(elasticsearch_indexing: true)
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index d7a23cfc796040bfb61ae7cd7ada459bd672a468..ba4429451d197727e7e0949adf3c98b13935db8b 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -306,7 +306,7 @@ RSpec.describe Issue do
   end
 
   describe '#reopen' do
-    let(:issue) { create(:issue, project: reusable_project, state: 'closed', closed_at: Time.current, closed_by: user) }
+    let_it_be_with_reload(:issue) { create(:issue, project: reusable_project, state: 'closed', closed_at: Time.current, closed_by: user) }
 
     it 'sets closed_at to nil when an issue is reopened' do
       expect { issue.reopen }.to change { issue.closed_at }.to(nil)
@@ -316,6 +316,22 @@ RSpec.describe Issue do
       expect { issue.reopen }.to change { issue.closed_by }.from(user).to(nil)
     end
 
+    it 'clears moved_to_id for moved issues' do
+      moved_issue = create(:issue)
+
+      issue.update!(moved_to_id: moved_issue.id)
+
+      expect { issue.reopen }.to change { issue.moved_to_id }.from(moved_issue.id).to(nil)
+    end
+
+    it 'clears duplicated_to_id for duplicated issues' do
+      duplicate_issue = create(:issue)
+
+      issue.update!(duplicated_to_id: duplicate_issue.id)
+
+      expect { issue.reopen }.to change { issue.duplicated_to_id }.from(duplicate_issue.id).to(nil)
+    end
+
     it 'changes the state to opened' do
       expect { issue.reopen }.to change { issue.state_id }.from(described_class.available_states[:closed]).to(described_class.available_states[:opened])
     end